If I don't pass in any options in the options hash, how does FileUtils behave when it fails?
I tried looking at FileUtils on ruby-doc.org and APIdock and couldn't find anything.
how does FileUtils behave when it fails?
Well, let's see:
require 'FileUtils'
puts Dir.pwd
#Existing dir:
FileUtils.cd("../python_programs")
puts Dir.pwd
FileUtils.cd("/does/not/exist")
--output:--
/Users/7stud/ruby_programs
/Users/7stud/python_programs
....`chdir': No such file or directory # dir_chdir - /does/not/exist (Errno::ENOENT)
So...you could do this:
require 'FileUtils'
begin
FileUtils.cd("/does/not/exist")
rescue Errno::ENOENT
puts "Couldn't switch directories"
end
--output:--
Couldn't switch directories
Or, even this:
require 'FileUtils'
paths = %w[
../python_programs
/does/not/exist
../rails_projects
]
paths.each do |path|
begin
FileUtils.cd(path)
puts "Just switched directories to: #{Dir.pwd}"
rescue Errno::ENOENT
puts "Couldn't switch to directory: #{path}"
end
end
--output:--
Just switched directories to: /Users/7stud/python_programs
Couldn't switch to directory: /does/not/exist
Just switched directories to: /Users/7stud/rails_projects
Related
In my main thor file, I call this code
script.rb
# this works
current_dir = Dir.getwd
# this changes directory into the tasks
Dir.chdir(#{pwd}/tasks) {
IO.popen("thor #{ARGV * ' '}") do |io|
while (line = io.gets) do
puts line
end
io.close
end
}
tasks/example.rb
require 'thor'
class Git < Thor
include Thor::Actions
desc 'test', 'test'
def test
puts Dir.getwd # this is showing my tasks folder
end
end
Inside example.rb How can I get access to the Dir.getwd value of the script.rb and not of the example.rb (this is wrong since it is running inside the Dir.chdir).
I tried global variables and such but it doesn't seem to be working.
Is it possible to get the location of the file which requires another file in Ruby?
I have a project where I spawn some processes and I would love to be able, in the code, to determine which file is the parent of the required file. This is nice when debugging.
Example:
#initial.rb:
require "./my_file.rb"
fork do
require "./my_file2.rb"
end
-
#my_file.rb:
puts "Required from file: #{?????}"
-
#my_file2.rb:
require "./my_file.rb"
I would expect to get something like:
#=> Required from file: /path/to/initial.rb
#=> Required from file: /path/to/my_file2.rb
Based on Jacobs answer I ended with this redefinition of require_relative and require:
alias :old_require_relative :require_relative
def require_relative(arg)
#~ puts caller.map{|x| "\t#{x}"}
puts "%s requires %s" % [ caller.first.split(/:\d+/,2).first, arg]
old_require_relative arg
end
alias :old_require :require
def require(arg)
#~ puts caller.map{|x| "\t#{x}"}
puts "%s requires %s" % [ caller.first.split(/:\d+/,2).first, arg]
old_require arg
end
In a test test scenario with the following load sequence:
test.rb
+- test1.rb
+- test1_a.rb
+ test2.rb
The following calls
require './test1'
require './test2'
or
require_relative 'test1'
require_relative 'test2'
result in:
test.rb requires ./test1
C:/Temp/test1.rb requires test1_a
test.rb requires ./test2
You could also include the line of the requirement in the output.
You should never need to do this, but you can examine the call stack from Kernel#caller. You'll have to filter out require methods (especially if you use any libraries that override require).
I have a method that zips up files I pass in.
require 'zip/zip'
def zipup(aname, aloc="/tmp/")
Zip::ZipFile.open "#{aloc}"+File.basename(aname)+".zip", Zip::ZipFile::CREATE do |zipfile|
zipfile.add File.basename(aname), aname
end
end
I need to get a string object or array object from this method that has the archive.zip name of every file that has been compressed.
rubyzip does have a to_s method all though I have failed in getting the syntax correct.
http://rubyzip.sourceforge.net/classes/Zip/ZipEntry.html#M000131
thanks from a new rubyist.
Welcome Joey, do you use the 'zip/zip' gem or just 'zip' ? If you require something, better add it to the question next time. This gem needs some extra documentation and methods it seems to me.
This works
require 'zip' #or 'zip/zip' both work
def zip_list(filename)
zipfile = Zip::ZipFile.open(filename)
list = []
zipfile.each { |entry| list << entry.name }
list
end
puts zip_list("c:/temp/zip1.zip")
another way
require 'zip/zip'
Zip::ZipFile.open("c:/temp/zip1.rb.zip") do |zipfile|
zipfile.entries.each do |entry|
puts entry.name
end
end
I am trying to access the insides of an ODT file. I'll run it through IRB and it will work perfectly fine but when I try and write a script to do it, it fails with this error:
./replace_odf.rb:3:in `require': no such file to load -- rubygems (LoadError)
from ./replace_odf.rb:3
Here is my code when ran through IRB. As you can see towards the end, it can access the file.
irb(main):001:0> require 'rubygems'
=> true
irb(main):002:0> require 'zip/zip'
=> true
irb(main):003:0> odt = Zip::ZipFile.open('java.odt')
=> java.odt
irb(main):004:0> odt.entries.each do |entry|
irb(main):005:1* puts entry.name
irb(main):006:1> end
mimetype
Configurations2/statusbar/
Configurations2/accelerator/current.xml
Configurations2/floater/
... etc
Here is my script code. When ran, it gives the error posted above.
require 'rubygems'
require 'zip/zip'
require 'rexml/document'
odt = Zip::ZipFile.open('java.odt')
file1 = odt.entries[0]
odt.entries.each do |entry|
puts entry.name if entry.name =~ /\.xml$/
end
puts odt.read("mimetype")
xml = odt.read("content.xml")
doc = REXML::Document.new(xml)
doc.root.each_element do |o|
o.each_element do |i|
puts i
end
end
I'm trying to create a local config file to use with compass so we can cope with differing import paths on developers' machines. So far I've tried to import the file inside an exception block, incase it doesn't exist, then use the variable further down:
local_config.rb
VENV_FOLDER = 'venv'
config.rb
VENV_FOLDER = '.'
begin
require 'local_config.rb'
rescue LoadError
end
puts VENV_FOLDER
Normally I'm a Python developer so I'd expect the import to change the value of VENV_FOLDER to venv, however it's still . afterwards.
Is there a way to import local_config.rb in such a way that it overrides the value of VENV_FOLDER?
Other alternatives:
YAML (or JSON)
local_config.yml
venv_folder: 'venv'
config.rb
require 'yaml'
VENV_FOLDER = begin
YAML.load_file('local_config.yml').fetch('venv_folder')
rescue Errno::ENOENT, KeyError
'.'
end
puts VENV_FOLDER
Class instance variable
You could put the value in a class instance variable:
local_config.rb
Config.venv = 'venv'
config.rb
class Config
class << self ; attr_accessor :venv ; end
self.venv = '.'
end
begin
require './local_config.rb'
rescue LoadError
end
puts Config.venv
Constants
Also, sticking to ruby files with constants, the following is perhaps marginally clearer in its intentions and avoids having to catch exceptions.
local_config.rb
VENV_FOLDER = 'venv'
config.rb
config_file = './local_config.rb'
require config_file if File.file? config_file
VENV_FOLDER ||= '.'
puts VENV_FOLDER
All three solutions have different mechanisms for ensuring that the value will be set even if the file is missing or doesn't set the value as expected. Hope it's helpful
The path to the file is wrong. It needs to include a slash if it isn't loaded from $LOAD_PATH.
Your LoadError is being caught silently.
If you do this:
VENV_FOLDER = '.'
begin
require './local_config.rb'
rescue LoadError
end
puts VENV_FOLDER
Then you'll see it works.
Better still:
VENV_FOLDER = '.'
require File.expand_path('../local_config.rb', __FILE__) rescue LoadError
puts VENV_FOLDER
Since the second version doesn't depend on the PWD of the user who invokes the script.
Constant re-assignment is a bad idea however. Ruby will let you do it, but you'll get a warning. I believe your confusion was just with the LoadError though.
Try something like this:
local_config.rb
VENV[:folder] = 'venv'
config.rb
VENV = {:folder => '.'}
begin
load 'local_config.rb'
rescue Exception
end
puts VENV[:folder]
Here's working version for ruby 1.9.3: https://gist.github.com/1501237
for ruby 1.8.7: https://gist.github.com/1501321