Patrick Doyle
10/8/2008 12:45:00 AM
[Note: parts of this message were removed to make it a legal post.]
Ahhh... I read "Ruby tries adding ``.rb'', ``.so'', and so on to the name"
in the documentation for #require over and over and it never occurred to me
that Ruby might not try loading the named file unadorned with an extension.
Thank you.
--wpd
On Tue, Oct 7, 2008 at 3:50 PM, Stefano Crocco <stefano.crocco@alice.it>wrote:
> Alle Tuesday 07 October 2008, Patrick Doyle ha scritto:
> > I started looking through the source code for rake and noticed something
> > curious.
> >
> > I see that when I execute the "rake" command at the command prompt, I run
> a
> > fairly trivial ruby script:
> >
> > require 'rubygems'
> >
> > version = ">= 0"
> >
> > if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then
> > version = $1
> > ARGV.shift
> > end
> >
> > gem 'rake', version
> > load 'rake'
> >
> > The #gem method prepended "..../gems/rake-0.8.3/bin" and
> > ".../gems/rake-0.8.3/lib" to my $LOAD_PATH (the "bin" directory first).
> > Thus, when the script invokes the #load method, it grabs
> > "..../gems/rake-0.8.3/bin/rake" and starts to execute it. It looks like
> > this:
> >
> > begin
> > require 'rake'
> > rescue LoadError
> > require 'rubygems'
> > require 'rake'
> > end
> > Rake.application.run
> >
> > Somehow, the "#require" method knows that it should load the "rake.rb"
> file
> > from the "lib" directory (the second element in $LOAD_PATH) instead of
> the
> > already loaded "rake" from the "bin" directory, (the fist element in
> > $LOAD_PATH).
> >
> > Why is that?
> >
> > --wpd
>
> According to the ri documentation for require, if you pass it a filename
> which
> doesn't have extension .rb or .so (or .dll or .o, depending on your
> system),
> then require tries to add those extensions to the file name and to load the
> corresponding library. So, the code
>
> require 'rake'
>
> will cause ruby to look for one of the files rake.rb or rake.so in the
> directories listed in $:. The script in bin is called simply rake, not
> rake.rb, and so require doesn't even consider it.
>
> load, instead, interpret its argument in a different way: it considers it
> to
> be the whole basename of the file and doesn't try to add any extension to
> it.
> So, the line
>
> load 'rake'
>
> will make ruby look for a file called 'rake' (not rake.rb as before) in the
> directories listed in $:. This time bin/rake has the correct name and is
> loaded.
>
> You can see it yourself by doing the following:
>
> * create a file with a name which doesn't end in .rb, for example
> test_load_require, then put some ruby code in it. Start irb in the same
> directory of the file and issue the command
>
> require 'test_load_require'
>
> ruby will complain (raising a LoadError) because it can't find the file.
> Now
> call
>
> load 'test_load_require'
>
> and you'll see that the file is correctly loaded and the code in it is
> executed.
>
> I hope this helps
>
> Stefano
>
>