How to change a file's path within ruby - ruby

I'm trying to move files from one folder to another via Ruby, but I'm stuck trying to get Pathname.new to work. For reference the files are being held in array as an inbetween from their normal dir. I know I could move it via CLI but I'd like the program to do it for me. This is what I have so far. I know it's wrong; I just don't get how to fix it.
temp_array.each {|song| song.path(Pathname.new("/Users/tsiege/Desktop/#{playlist_name}"))}

Have a look at FileUtils.mv:
require 'fileutils'
temp_array.each do |song|
FileUtils.mv song.path, "/Users/tsiege/Desktop/#{playlist_name}"
end
Be sure that the directory #{playlist_name} exists before you do, though:
FileUtils.mkdir_p "/Users/tsiege/Desktop/#{playlist_name}"

To move files you can use FileUtils.mv:
require 'fileutils'
FileUtils.mv 'from.ext', 'to.ext'
http://ruby-doc.org/stdlib-1.9.3/libdoc/fileutils/rdoc/FileUtils.html#method-c-mv
And if you want a list of files in a directory you can use:
Dir['/path/to/dir/*']
http://ruby-doc.org/core-1.9.3/Dir.html
Lastly, you may also want to check if you have a file or directory:
File.file? file
File.directory? dir
http://ruby-doc.org/core-1.9.3/File.html#method-c-file-3F

Related

FileUtils.mkdir_p support for wildcards in ruby?

I have for example directory structure like this:
./DIRECTORY/PROJECT_A/cars/
./DIRECTORY/PROJECT_B/planes/
./DIRECTORY/PROJECT_C/bikes/
I would like to recourse through them using wildcards and create other directory's, like this:
Dir['/DIRECTORY/PROJECT_*/*/'].each do FileUtils.mkdir_p 'TheNewDirectory'.
It seems "FileUtils" doesn't support wildcards.
I'm doing the same for creation of files on this way:
Dir['/DIRECTORY/PROJECT_*/*/'].each do |dir|
File.new File.join(dir, 'myFile.txt'), 'w+'
end
So I would like to do the same but for creation of directories. Any idea?
FileUtils is a module. It doesn't make sense to claim that a module "does not use wildcards".
Moreover, you are using only the function mkdir_p from FileUtils, and do not use any wildcard in its argument, so what you say, doesn't apply to your case either.
What happened is, that your are iterating through all the directories entries created by your Dir[...] expression, but then don't use the actual directory! A first step to write this better would be
Dir['/DIRECTORY/PROJECT_*/*/'].each { |d| FileUtils.mkdir_p("#{d}/TheNewDirectory") }
This works however only if it is guaranteed that d never takes the value of a plain file, and of course you can run this code only once (because the second time, you would obviously create directories of the form /DIRECTORY/PROJECT_FOO/BAR/TheNewDirectory/TheNewDirectory. I would therefore check, for the safe side, that it indeed makes sense to create the directory, before doing it.
To create directory, you need to specify full path of new directory using the current folder name:
Dir['/DIRECTORY/PROJECT_*/*/'].each do |f|
FileUtils.mkdir_p "#{f}/TheNewDirectory" if File.directory?(f)
end

Error reading local file in Sinatra

I'm trying to write a Sinatra app that reads in a list from a file, and then spits back a random item from that list.
I'm having trouble figuring out the path to the file to read it, though. Sinatra says 'no such file or directory' when I try to load an item in my browser:
Errno::ENOENT at /wod
No such file or directory - http://localhost:4567/listing.txt
Here is the code:
require 'sinatra'
#list
get /item
puts read_list[rand(#list.size)]
end
def read_list
File.open('listing.txt', 'r').readlines
end
I have the file in /public, which the Sinatra README says is the default location for hosting static files. Furthermore, if I put it in /public I can navigate to localhost:4567/listing.txt and read the file in the browser.
A couple things I noticed:
get /item
isn't correct, it should be:
get '/item' do
If you start your code inside the same directory the Ruby code is in, the current working-directory will be ".", which is where Ruby will look when trying to:
File.open('listing.txt', 'r').readlines
Ruby will actually use './listing.txt' as the path. That's OK if you manually launch the code from the root directory of the application, but that doesn't work well if you try to launch it from anywhere else.
It's better to be explicit about the location of the file when you're actually trying to load something for use with a web server. Instead of relying on chance, there are a couple things you can do to help make it more bullet-proof. Consider this:
def read_list
running_dir = File.dirname(__FILE__)
running_dir = Dir.pwd if (running_dir == '.')
File.open(running_dir + '/public/listing.txt', 'r').readlines
end
File.dirname gets the path information from __FILE__, which is the absolute path and name of the current file running. If the application was started from the same directory as the file, that will be ., which isn't what we want. In that case, we want the absolute path of the current working-directory, which Dir.pwd returns. Then we can append that to the path of the file you want, from the root of the application.
You'll need to do File.read('public/listing.txt', 'r') to get what you want here.
File.open isn't part of Sinatra and doesn't know to look in a specific place for static files, so it just looks in the current working directory.

Ruby require path

I have a Ruby code with different classes in a few files. In one file, I start the execution. This file requires my other files.
Is this a good way to start a ruby code?
When I run the code from a symbolic link, for example DIR2/MyRubyCode is a link to the main file DIR1/MyRubyCode.rb, then my requires will fail. I solved the problem by adding the path DIR1 to $LOAD_PATH before the require, but I think there would be much better ways to do it. Do you have any suggestions about that?
If you're using Ruby 1.9 or greater, user require_relative for your dependencies.
require_relative 'foo_class'
require_relative 'bar_module'
If you want to check if a Ruby file is being 'require'ed or executed with 'ruby MyRubyCode.rb', check the __FILE__ constant.
# If the first argument to `ruby` is this file.
if $0 == __FILE__
# Execute some stuff.
end
As far as the require/$LOAD_PATH issue, you could always use the relative path in the require statement. For example:
# MyRubyCode.rb
require "#{File.dirname(__FILE__)}/foo_class"
require "#{File.dirname(__FILE__)}/bar_module"
Which would include the foo_class.rb and bar_module.rb files in the same directory as MyRubyCode.rb.
I know this is an old question, but there is an updated answer to it, and I wanted to post it:
Starting in a more recent version of Ruby (I'm not sure when), you can require files in the same directory by using the following:
require './foo_class'
require './bar_module'
and it'll load files called foo_class.rb and bar_module.rb in the same directory.
For checking if your file is being required or ran normally, check the other answer.

Is it possible to recursively require all files in a directory in Ruby?

I am working on an API that needs to load all of the .rb files in its current directory and all subdirectories. Currently, I am entering a new require statement for each file that I add but I would like to make it where I only have to place the file in one of the subdirectories and have it automatically added.
Is there a standard command to do this?
In this case its loading all the files under the lib directory:
Dir["#{File.dirname(__FILE__)}/lib/**/*.rb"].each { |f| load(f) }
require "find"
Find.find(folder) do |file|
next if File.extname(file) != ".rb"
puts "loading #{file}"
load(file)
end
This will recursively load each .rb file.
like Miguel Fonseca said, but in ruby >= 2 you can do :
Dir[File.expand_path "lib/**/*.rb"].each{|f| require_relative(f)}
I use the gem require_all all the time, and it gets the job done with the following pattern in your requires:
require 'require_all'
require_all './lib/exceptions/'
def rLoad(dir)
Dir.entries(dir).each {|f|
next if f=='.' or f=='..'
if File.directory?(f)
rInclude(f)
else
load(f) if File.fnmatch('*.rb', f)
end
}
end
This should recursively load all .rb files in the directory specified by dir. For example, rLoad Dir.pwd would work on the current working directory.
Be careful doing this, though. This does a depth-first search and if there are any conflicting definitions in your Ruby scripts, they may be resolved in some non-obvious manner (alphabetical by folder/file name I believe).
You should have a look at this gem. It is quite small so you can actually re-use the code instead of installing the whole gem.

Linking to external files in ruby?

Sorry if this question is very easy, but I can't find the answer anywhere. How do you refer to an external ruby file in a ruby script if, for example, the file you want is in the same folder as the one you are writing?
Thanks in advance.
You just do a require like this require "filename". Ruby will look in each of the paths in the $LOAD_PATH variable to find the file.
Have a look at $LOAD_PATH and you should get something like this:
irb(main):001:0> puts $LOAD_PATH
/usr/local/lib/ruby/site_ruby/1.8
/usr/local/lib/ruby/site_ruby/1.8/i686-darwin10.0.0
/usr/local/lib/ruby/site_ruby
/usr/local/lib/ruby/vendor_ruby/1.8
/usr/local/lib/ruby/vendor_ruby/1.8/i686-darwin10.0.0
/usr/local/lib/ruby/vendor_ruby
/usr/local/lib/ruby/1.8
/usr/local/lib/ruby/1.8/i686-darwin10.0.0
.
You can see that the last entry is the current directory.
You can also give a path specifically like require "lib/filename.rb"
require "YOUR_EXTERNAL_FILE_NAME_WITHOUT_DOT_RB_EXTENSION"
For example, if you have two files, 'file0.rb' and 'file1.rb' and want to include 'file0.rb' from 'file1.rb' (and both files are in the same folder), your 'file1.rb' should have following statement:
require 'file0'

Resources