How can I create a new file in a specific directory. I created this class:
class FileManager
def initialize()
end
def createFile(name,extension)
return File.new(name <<"."<<extension, "w+")
end
end
I would like to specify a directory (path) where to create the file. If this one doesn't exist, he will be created. So do I have to use fileutils as shown here just after file creation or can I specify directly in the creation the place where create the file?
Thanks
The following code checks that the directory you've passed in exists (pulling the directory from the path using File.dirname), and creates it if it does not. It then creates the file as you did before.
require 'fileutils'
def create_file(path, extension)
dir = File.dirname(path)
unless File.directory?(dir)
FileUtils.mkdir_p(dir)
end
path << ".#{extension}"
File.new(path, 'w')
end
Related
I have a program that asks with the termial to write the name of the directory that the user wants, like this $ ruby app.rb mysuperdirectory
def get_ directory_name
return directory_name = ARGV.first
end
def create_ directory(name)
Dir.mkdir(name)
end
def perform
directory_name = get_ directory_name
create_ directory(directory_name)
end
perform
I will automatically want to create a lib directory Dir.mkdir("lib") and put it in the directory mysuperdirectory .
In this mysuperdirectory that the user has just created with lib inside, I would like to make a system("git init")and system("rspec --init")
How can I do all this?
Thanks
You can use Dir.chdir to change directory.
def perform
directory_name = get_ directory_name
create_ directory(directory_name)
create_ directory("#{directory_name}/lib")
Dir.chdir(directory_name) do
system("git init")
system("rspec --init")
end
end
I am working on creating a plugin in Ruby.
On this moment I am unable to insert the coordinates, that are added to a Sketchup model, in a .txt file.
This is my code:
require 'sketchup.rb'
SKETCHUP_CONSOLE.show rescue Sketchup.send_action("showRubyPanel:")
$stdout = File.new('file.txt', 'w')
module HWmakemyownplug
def self.fileplug
model = Sketchup.active_model
#Make some coordinates.
coordinates = [[2,0,39],[0,0,1],[1,1,0]]
#Add the points in Sketchup. This works!
coordinates.each { |point| model.active_entities.add_cpoint(point) }
#Puts the coordinates to the textfile 'file.txt'. This doesn't work!
$stdout.puts(coordinates)
end #def self.fileplug
end #module makemyownplug
if (!file_loaded?(__FILE__))
#Add to the SketchUp tools menu
extensions_menu = UI.menu("Plugins")
extensions_menu.add_item("testtesttest") { HWmakemyownplug::fileplug }
# Let Ruby know we have loaded this file
file_loaded(__FILE__)
end
The coordinates have to be printed when I click on menu > plugins > testtesttest.
You forgot to close file after $stdout.puts(coordinates)
$stdout.close
Here is an example code for writing data to a JSON file instead of a simple text document.
The code can run outside of SketchUp for testing in the terminal. Just make sure to follow these steps...
Copy the code below and paste it on a ruby file (example: file.rb)
Run the script in terminal ruby file.rb or run with SketchUp.
The script will write data to JSON file and also read the content of JSON file.
The path to the JSON file is relative to the ruby file created in step one. If the script can't find the path it will create the JSON file for you.
module DeveloperName
module PluginName
require 'json'
require 'fileutils'
class Main
def initialize
path = File.dirname(__FILE__)
#json = File.join(path, 'file.json')
#content = { 'hello' => 'hello world' }.to_json
json_create(#content)
json_read(#json)
end
def json_create(content)
File.open(#json, 'w') { |f| f.write(content) }
end
def json_read(json)
if File.exist?(json)
file = File.read(json)
data_hash = JSON.parse(file)
puts "Json content: #{data_hash}"
else
msg = 'JSON file not found'
UI.messagebox(msg, MB_OK)
end
end
# # #
end
DeveloperName::PluginName::Main.new
end
end
I'm writing a simple gem that can load from and save data to text files and zip archives. So, it has four methods: load_from_file, load_from_zip, save_to_file and save_to_zip respectfully. The problem is that I can't figure out how to specify relative paths for loading and saving for these methods. Here they go:
def load_from_file(filename)
File.open(filename) do |f|
f.each { |line| add(line) } # `add` is my another class method
end
end
def load_from_zip(filename)
Zip::File.open("#{filename}.zip") do |zipfile|
zipfile.each { |entry| read_zipped_file(zipfile, entry) } # my private method
end
end
def save_to_file(filename)
File.write("#{filename}.txt", data)
end
def save_to_zip(filename)
Zip::File.open("#{filename}.zip", Zip::File::CREATE) do |zipfile|
zipfile.get_output_stream('output.txt') { |f| f.print data }
end
end
private
def read_zipped_file(zipfile, entry)
zipfile.read(entry).lines.each { |line| add(line) }
end
So what I want basically is to allow this gem to load and save files by relative paths whereever it is used in system, e.g. I have an app located in /home/user/my_app with two files - app.rb and data.txt, and I could be able to read the file from this directory without specifying absolute path.
Example:
# app.rb
require 'my_gem'
my_gem = MyGem.new
my_gem.load_from_file('data.txt')
(Sorry for bad English)
UPD: This is not Rails gem and I'm not using Rails. All this is only pure Ruby.
Short answer
If I understand it correctly, you don't need to change anything.
Inside app.rb and your gem, relative paths will be understood relatively to Dir.pwd.
If you run ruby app.rb from inside /home/user/my_app :
Dir.pwd will be /home/user/my_app
both app.rb and my_gem will look for 'data.txt' inside /home/user/my_app.
Useful methods, just in case
Dir.chdir
If for some reason Dir.pwd isn't the desired folder, you could change directory :
Dir.chdir('/home/user/my_app') do
# relative paths will be based from /home/user/my_app
# call your gem from here
end
Get the directory of current file :
__dir__ will help you get the directory :
Returns the canonicalized absolute path of the directory of the file
from which this method is called.
Get the current file :
__FILE__ will return the current file. (Note : uppercase.)
Concatenate file paths :
If you need to concatenate file paths, use File.expand_path or File.join. Please don't concatenate strings.
If you don't trust that the relative path will be correctly resolved, you could send an absolute path to your method :
my_gem.load_from_file(File.expand_path('data.txt'))
I am making a command line tool and I am using yaml to make a config file. But right now I can only access the tool when I am in the same directory as that of myprogram.yml.
private
CONFIG_FILE = 'myprogram.yml'
def write_config
config = {}
config['username']=#username
config['password']=#password
File.open(CONFIG_FILE, 'w') do |f|
f.write config.to_yaml
end
end
def read_config
config = YAML.load_file(CONFIG_FILE)
#username = config['username']
#password = config['password']
end
How can I make this file to be accessed from any directory on my computer?
You'll want to give the absolute directory of the myprogram.yml file. Right now it will look in the directory where you are executing the ruby script from. By making it absolute, the script can run anywhere and know where to find the config file.
Example:
private
CONFIG_FILE = '/Users/myuser/config/myprogram.yml'
def write_config
config = {}
config['username']=#username
config['password']=#password
File.open(CONFIG_FILE, 'w') do |f|
f.write config.to_yaml
end
end
def read_config
config = YAML.load_file(CONFIG_FILE)
#username = config['username']
#password = config['password']
end
In a folder I have random module files.
eg. "user.rb" that contains "module User", "customer.rb" that contains "module Customer" and so on.
I want to require all files and print out all module methods.
Here is my current code:
##data_module_methods = []
# iterate through all files in the data folder
Dir[File.join(APP_ROOT, "data", "*.rb")].each do |file|
require file
# give me the module name from the filepath (so ./data/user.rb will give me User)
data_module_name = file.split("/").[](-1).split(".").[](0).capitalize
# ERROR: print all method names, HERE IT FAILS BECAUSE data_module_name is a string and not the module:)
data_module_name.instance_methods.each do |method|
##data_module_methods << method
end
end
How could i do this?
Thanks
You can use the Kernel#const_get method to get every module by its name, so:
...
Kernel.const_get(data_module_name).instance_methods.each do |method|
...