[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

load vs require

Patrick Doyle

10/7/2008 7:29:00 PM

[Note: parts of this message were removed to make it a legal post.]

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

2 Answers

Stefano Crocco

10/7/2008 7:51:00 PM

0

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

Patrick Doyle

10/8/2008 12:45:00 AM

0

[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
>
>