Why isn't current directory on my Ruby path? [duplicate] - ruby

This question already has answers here:
Why does Ruby 1.9.2 remove "." from LOAD_PATH, and what's the alternative?
(7 answers)
Closed 8 years ago.
Is there any reason why my present working directory is not on my Ruby path?
Consider:
~:499$ irb
ruby-1.9.2-p136 :002 > puts $:
/Users/mrberryman/.rvm/rubies/ruby-1.9.2-p136/lib/ruby/site_ruby/1.9.1
/Users/mrberryman/.rvm/rubies/ruby-1.9.2-p136/lib/ruby/site_ruby/1.9.1/x86_64-darwin10.6.0
/Users/mrberryman/.rvm/rubies/ruby-1.9.2-p136/lib/ruby/site_ruby
/Users/mrberryman/.rvm/rubies/ruby-1.9.2-p136/lib/ruby/vendor_ruby/1.9.1
/Users/mrberryman/.rvm/rubies/ruby-1.9.2-p136/lib/ruby/vendor_ruby/1.9.1/x86_64-darwin10.6.0
/Users/mrberryman/.rvm/rubies/ruby-1.9.2-p136/lib/ruby/vendor_ruby
/Users/mrberryman/.rvm/rubies/ruby-1.9.2-p136/lib/ruby/1.9.1
/Users/mrberryman/.rvm/rubies/ruby-1.9.2-p136/lib/ruby/1.9.1/x86_64-darwin10.6.0
=> nil
This is really bothering me because require isn't working as I thought it would (although I'm a ruby nuby):
require 'some_file_that_I_know_darn_well_is_in_pwd.rb'
If I append '.' to the end, then the require works as I'd expect.
What am I missing?
UPDATE:
Arg! Now I'm getting a new problem. Consider:
ruby-1.9.2-p136 :010 > `ls`
=> "start.rb\n"
ruby-1.9.2-p136 :011 > require_relative 'start'
LoadError: cannot infer basepath
from (irb):11:in `require_relative'
from (irb):11
from /Users/mrberryman/.rvm/rubies/ruby-1.9.2-p136/bin/irb:16:in `<main>'
Now what's up?

In Ruby 1.9.2 the Powers that Be introduced an explicit change so that the working directory is no longer in the Ruby path. I thought it was the Apocalypse and a terrible thing, until I learned about require_relative. My apps tend to look like this:
require 'some_gem'
require 'another_gem'
require_relative 'lib/init'
And then lib/init.rb can have:
require_relative 'lib1' # this is lib/lib1.rb
require_relative 'lib2' # this is lib/lib2.rb
It's the bees knees, and solves all sorts of problems I used to have with requiring the same file from different working directories.
Edit: Unfortunately (for reasons I don't know and haven't looked into) require_relative doesn't work specifically in irb. For this you can:
do what you initially described: either $: << '.' or $:.unshift '.', or
you can use load 'myfile.rb' or require './myfile' instead:
irb(main):001:0> Dir['*.rb']
=> ["a.rb", "bar.rb", "foo.rb", "prime.rb", "tmp.rb"]
irb(main):002:0> require 'a'
LoadError: no such file to load -- a
from <internal:lib/rubygems/custom_require>:29:in `require'
from <internal:lib/rubygems/custom_require>:29:in `require'
from (irb):2
from /usr/local/bin/irb:12:in `<main>'
irb(main):003:0> require_relative 'a'
LoadError: cannot infer basepath
from (irb):3:in `require_relative'
from (irb):3
from /usr/local/bin/irb:12:in `<main>'
irb(main):004:0> load 'a.rb'
a
=> true
irb(main):005:0> require './a'
a
=> true

You can use require_relative assuming it does what you need.

Make sure that the environment variable "RUBYLIB" is set with all directory paths where you will find custom *.rb code. It drove me nuts too.

Related

require not working on ruby 2.0?

I'm doing a test with "require" under ruby 2.0.0p576 (2014-09-19 revision 47628) [x86_64-darwin13.4.0] it doesn't work in many ways.
There are two files in ruby directory as shown below:
string_extensions.rb
class String
def vowels
self.scan(/[aeiou]/i)
end
end
vowels_test.rb
require 'string_extensions'
puts "This is a test".vowels.join('-')
fire up IRB
Snailwalkers-MacBook-Pro:ruby snailwalker$ ruby vowels_test.rb
returs : `require': cannot load such file -- string_extensions (LoadError)
I tried to change require 'string_extensions' to " require_relative 'string_extensions' ; require './string_extensions.rb' . They all didn't work.
both return error : vowels_test.rb:1:in require_relative': /Users/snailwalker/Ruby/string_extensions.rb:1: class/module name must be CONSTANT (SyntaxError)
Your help will be greatly appreciated!
You can use require_relative instead:
require_relative 'string_extensions'
puts "This is a test".vowels.join('-')
Or even require './string_extensions'.
Use:
ruby -I. vowels_test.rb
Automatic inclusion of the current directory in the load paths was removed in Ruby 2.

Require not able to find ruby file

I am an absolute beginner in Ruby. I created a small ruby file, and it runs well when I run the command ruby "methods.rb". That means I am in the correct directory.
But when I launch irb and run the command require "methods.rb", I get the following response:
LoadError: cannot load such file -- methods.rb
from /usr/local/rvm/rubies/ruby-1.9.3-p392/lib/ruby/site_ruby/1.9.1/rubygems/core_ext/kernel_require.rb:53:in `require'
from /usr/local/rvm/rubies/ruby-1.9.3-p392/lib/ruby/site_ruby/1.9.1/rubygems/core_ext/kernel_require.rb:53:in `require'
from (irb):1
from /usr/local/rvm/rubies/ruby-1.9.3-p392/bin/irb:16:in `<main>'
Ruby doesn't add the current path to the load path by default.
From irb, you can try require "./methods.rb" instead.
I do have a ruby file called so.rb in the directory /home/kirti/Ruby. So first from IRB I would change my current working directory using Dir#chdir method. Then I would call #load or #require method. My so.rb file contains only p hello line.
I would go this way :
>> Dir.pwd
=> "/home/kirti"
>> Dir.chdir("/home/kirti/Ruby")
=> 0
>> Dir.pwd
=> "/home/kirti/Ruby"
>> load 'so.rb'
"hello"
=> true
>> require './so.rb'
"hello"
=> true
To add the directory you are executing the ruby script from to the load path use:
$LOAD_PATH.unshift( File.join( File.dirname(__FILE__), '' ) )
or if you have put your dependencies in 'subdir' of the current directory:
$LOAD_PATH.unshift( File.join( File.dirname(__FILE__), 'subdir' ) )
If you are going to load things in IRB that are in your current directory, you can do:
irb -I.
Note the 'dot' there, indicating current directory.
If you are exploring and making changes in that file, while you are in IRB, use load rather than `require as load lets you load your changes, and require will only allow the file to be required once. This means you will not need to exit IRB to see how your changes are being affected.
To find out what options you have for IRB, you can do irb --help which is good to do if you are learning the tool.

require can't find an .rb file that's the same directory

How exactly does the require command in Ruby work? I tested it with the following two files that are in the same directory.
test.rb
require 'requirements'
square(2)
requirements.rb
def square(x)
x*x
end
But when I run ruby test.rb while I'm in the same directory as the files "test.rb" and "requirements.rb", I get the error:
/usr/local/rvm/rubies/ruby-1.9.3-p286/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require': cannot load such file -- requirements (LoadError)
from /usr/local/rvm/rubies/ruby-1.9.3-p286/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
from test.rb:1:in `<main>'
which I think means it can't find the requirements.rb file. But it's in the same directory as test.rb! How does one fix this?
Much thanks in advance. I apologize for such noob questions.
IIRC, ruby 1.9 doesn't include current dir ('.') to LOAD_PATH. You can do one of these:
# specify relative path
require './test1'
# use relative method
require_relative 'test1'
# add current dir to LOAD_PATH
$LOAD_PATH.unshift '.'
require 'test1'
I too just started to learn how ruby works, so I'm not perfectly sure if this helps. But try require_relative instead of require and I think it will work.
Afaik require searches in the ruby libary.

I18n without Rails?

just having troubles to make I18n to work without Rails environment:
irb> require 'i18n'
=> true
irb> I18n.load_path=Dir['/usr/lib/ruby/gems/1.9.1/gems/rails-i18n-0.6.6/rails/locale/en.yml']
=> ["/usr/lib/ruby/gems/1.9.1/gems/rails-i18n-0.6.6/rails/locale/en.yml"]
irb> I18n.load_path+=Dir['/usr/lib/ruby/gems/1.9.1/gems/rails-i18n-0.6.6/rails/locale/sk.yml']
=> ["/usr/lib/ruby/gems/1.9.1/gems/rails-i18n-0.6.6/rails/locale/en.yml", "/usr/lib/ruby/gems/1.9.1/gems/rails-i18n-0.6.6/rails/locale/sk.yml"]
irb> I18n.locale=:sk
=> :sk
irb> I18n.default_locale=:sk
=> :sk
irb> I18n.l Time.now
I18n::MissingTranslationData: translation missing:
sk.time.formats.default
from /usr/lib/ruby/gems/1.9.1/gems/i18n-0.6.1/lib/i18n.rb:289:in
`handle_exception'
from /usr/lib/ruby/gems/1.9.1/gems/i18n-0.6.1/lib/i18n.rb:159:in
`translate'
from
/usr/lib/ruby/gems/1.9.1/gems/i18n-0.6.1/lib/i18n/backend/base.rb:55:in
`localize'
from /usr/lib/ruby/gems/1.9.1/gems/i18n-0.6.1/lib/i18n.rb:236:in
`localize'
from (irb):11
from /usr/bin/irb:12:in `<main>'
irb>
What am I doing wrong ? The sk.yml DOES contain sk.time.formats.default
element !!
In addition what's the I18n's default load_path(s) so I won't be
bothered to supply full paths to every translation YAML/Ruby file ?
Thanks.
You already set the search path for the language definitions with I18n.load_path.
It seems, this is enough when using rails. Without rails, you must also load the language definitions with I18n.backend.load_translations.
In summary, you need two steps:
I18n.load_path = Dir['*.yml']
I18n.backend.load_translations
The dictionaries are defined with language key, e.g. like:
en:
hello: "Hello world"
If you prefer to define your en.yml without language key, you may load them via
I18n.backend.store_translations(:en , YAML.load(File.read('en.yml')))
(You may also use a here-document or direct a ruby-hash).
It seems like your load_path is not being set correctly.
Try including the whole directory and if it's successful, you should see your :sk and :en files by calling I18n.load_path.
I18n.load_path = Dir['/usr/lib/ruby/gems/1.9.1/gems/rails-i18n-0.6.6/rails/locale/*yml']
Setting the files paths directly can be a bit confusing since I18n won't raise an error if the file doesn't exist.
As a side note, I'd advise against including translations from the rails-i18n gem as the path may be different from one machine to another with different ruby versions etc.. a file local to the project would be better.
You'll need to install rails-i18n gem just to get localization data.
With this gem install, one can e.g. print month names in sk localization with:
require 'rails-i18n'
I18n.load_path += $LOADED_FEATURES
.select {|f| "rails-i18n.rb".in? f }
.collect {|f| f.sub('lib/rails-i18n.rb', 'rails/locale/sk.yml') }
I18n.locale = :sk
puts I18n.t('date.month_names').compact
This yields:
Január
Február
Marec
Apríl
Máj
Jún
Júl
August
September
Október
November
December

Ruby - LoadError on require

I have the following two files: main.rb and sort.rb located in the same folder. In main.rb I have the following code:
require 'sort'
Sort.insertion_sort([1,2,3,4]).each {|x| print "#{x}, "}
When I try and run this via ruby main.rb I get the following error:
<internal:lib/rubygems/custom_require>:29:in `require': no such file to load -- sort (LoadError)
from <internal:lib/rubygems/custom_require>:29:in `require'
from main.rb:1:in `<main>'
Any ideas why?
Thanks
The better way to use
require_relative "sort"
intead of
require "sort"
Thanks, #Jörg W Mittag.
Or you can add a path where ruby should search your files (can be a security risk):
$:.unshift File.join(File.dirname(__FILE__), ".") # current directory
require 'sort'
try require 'sort.rb' and check permissions
you would also:
require directory/sort.rb
In Ruby 1.9.2, $: doesn't include the current directory ('.'). Either do relative_require instead, or do $: << '.'.
Joerg Mittag says that $: << '.' shouldn't be done because it's a security risk.

Resources