Require command not working within bash irb on Snow Leopard
This is because the working directory is no longer in the Ruby path in Ruby 1.9.2. This does work:
require './ex25'
Why isn't current directory on my Ruby path?
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'
orrequire './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
loading documents on IRB ruby
It depends on the version of Ruby you are using (1.8.x or 1.9.x). load
and require
work both on the loadpath of Ruby. You can have a look at it by evaluating $:
inside IRB. In Ruby 1.9.x the current directory is not part of the loadpath, so you have to use the absolute path to your file. Depending on the operating system you are using (Windows 7), this may look like:
c:\Users\mliebelt\Desktop>irb
irb(main):001:0> $:
=> ["C:/apps/ruby/ruby192/lib/ruby/site_ruby/1.9.1", "C:/apps/ruby/ruby192/lib/ruby/site_ruby/1.9.1/i386-msvcrt", "C:/apps/ruby/ruby192/lib/ruby/site_ruby", "C:/apps/ruby/ruby192/lib/ruby/vendor_ruby/1.9.1", "C:/apps/ruby/ruby192/lib/ruby/vendor_ruby/1.9.1/i386-msvcrt", "C:/apps/ruby/ruby192/lib/ruby/vendor_ruby", "C:/apps/ruby/ruby192/lib/ruby/1.9.1", "C:/apps/ruby/ruby192/lib/ruby/1.9.1/i386-mingw32"]
irb(main):002:0> require 'c:/Users/mliebelt/Desktop/ruby'
File c:/Users/mliebelt/Desktop/ruby.rb loaded.
=> true
irb(main):003:0> load 'c:/Users/mliebelt/Desktop/ruby.rb'
File c:/Users/mliebelt/Desktop/ruby.rb loaded.
=> true
By the way, the contents of the file ruby.rb
is:
puts "File #{__FILE__} loaded."
The same session with IRB on Ruby 1.8.x may look like that:
c:\Users\mliebelt\Desktop>irb
irb(main):001:0> $:
=> ["C:/Users/mliebelt/.pik/rubies/Ruby-187-p334/lib/ruby/site_ruby/1.8", "C:/Users/mliebelt/.pik/rubies/Ruby-187-p334/lib/ruby/site_ruby/1.8/i386-msvcrt", "C:/Users/mliebelt/.pik/rubies/Ruby-187-p334/lib/ruby/site_ruby", "C:/Users/mliebelt/.pik/rubies/Ruby-187-p334/lib/ruby/vendor_ruby/1.8", "C:/Users/mliebelt/.pik/rubies/Ruby-187-p334/lib/ruby/vendor_ruby/1.8/i386-msvcrt", "C:/Users/mliebelt/.pik/rubies/Ruby-187-p334/lib/ruby/vendor_ruby", "C:/Users/mliebelt/.pik/rubies/Ruby-187-p334/lib/ruby/1.8", "C:/Users/mliebelt/.pik/rubies/Ruby-187-p334/lib/ruby/1.8/i386-mingw32", "."]
irb(main):002:0> require 'ruby'
File ./ruby.rb loaded.
=> true
irb(main):003:0> load 'ruby.rb'
File ./ruby.rb loaded.
=> true
The differences between require
and load
are:
require
does not need the suffix (.rb) of the filerequire 'ruby'
andrequire 'ruby.rb'
are the same
require
reads the file into memory once, sorequire
should normally be used instead ofload
, which reads the file into memory every time functions in the file are called.
So to load files (by using require
or load
), do the following:
- expand your load path by your current directory (if necessary). See Adding a directory to loadpath
- (when using Ruby 1.8.x) Start your program (or IRB) in the directory from which you want to load or require files.
Can you 'require' ruby file in irb session, automatically, on every command?
I usually create a simple function like this:
def reload
load 'myscript.rb'
# Load any other necessary files here ...
end
With that, a simple reload
will re-import all of the scripts that I'm working on. It's not automatic, but it's the closest thing that I've been able to come up with.
You may be able to override method_missing
to call this function automatically when your object is invoked with a method that doesn't exist. I've never tried it myself, though, so I can't give any specific advice. It also wouldn't help if you're calling a method that already exists but has simply been modified.
In my own laziness, I've gone as far as mapping one of the programmable buttons on my mouse to the key sequence "reload<enter>". When I'm using irb
, all it takes is the twitch of a pinky finger to reload everything. Consequently when I'm not using irb
, I end up with the string "reload" inserted in documents unintentionally (but that's a different problem entirely).
The command ruby does nothing on my Mac
Ruby command itself will just behave the way you said, either provide it with script file or use the -e option:
ruby -e ' puts "hello world" '
However I suspect that you want the IRB(interactive ruby). Run irb
in your shell.
Ruby Include Module in IRB
That's an error in the book. The methods in Ex25
are class methods. include
adds instance methods to the "current space." Remove self
from the method definitions and it'll work:
module Ex25
def break_words(stuff)
stuff.split(' ')
end
end
include Ex25
break_words 'hi there' # => ["hi", "there"]
If you're curious, here's some more detail about what's going on: The place where the methods are included—the "current space"—is the Object class:
Object.included_modules # => [Ex25, Kernel]
All Object instances gain the included methods ...
Object.new.break_words 'how are you?' # => ["how", "are", "you?"]
... and the top-level is just an Object instance:
self.class # => Object
But wait. If the top-level is an Object instance, why does it respond to include
? Isn't include
an instance method of Module
(and its subclass, Class
)? The answer is that the top-level has a singleton method ...
singleton_methods.include? "include" # => true
... which we can assume forwards to the Object class.
Related Topics
How Are Respond_To and Respond_To_Missing Different
Trouble with Google Apps API and Service Accounts in Ruby
Respond_With Redirect with Notice Flash Message Not Working
Unescaping Characters in a String with Ruby
How to Install "Readline" for Rails Console
Controller Method #Show Getting Called
Ruby: How Does Constant-Lookup Work in Instance_Eval/Class_Eval
How to Set Correct Ruby Version in Gem Environment
Ruby - Return Byte Array Containing Two's Complement Representation of Bignum/Fixnum
Getting Count of Elements by 'Created_At' by Day in a Given Month
Vagrant Ssh Not Working in Mobaxterm on Windows
Error Installing "Kgio-2.9.2" Gem on Windows
Rails Reload Dynamic Routes on Multiple Instances/Servers
Nesting Too Deep' Error While Retrieving JSON Using Httparty
How to Mock an Instance Method of an Already Mocked Object
Rails: Rake Db:Create:All (Could Not Connect to Server)
Rails 3 Caching: Expire Action for Named Route
Undefined Method 'Require_Relative' for Main:Object (Nomethoderror)