David Vallner
12/3/2006 7:07:00 PM
Allison Newman wrote:
> lrlebron@gmail.com wrote:
>> You can change the code one of two ways to get it to work
>>
>> This way which is useful if you want, for example, to use a particular
>> version of the library
>>
>> require 'rubygems'
>> require 'net/http'
>> require 'uri'
>> require_gem 'hpricot', '=0.4'
>> require 'hpricot'
>>
>> or this way to use the latest version
>>
>> require 'net/http'
>> require 'uri'
>> require 'hpricot'
>>
>> Luis
>
> Ahhh, ok, so I have to require 'hpricot' regardless of whether I have
> already done a require_gem 'hpricot'. Seems a little odd that! I'll
> have to add it to my list of "not principle of least surprise" examples
> :-) Thankyou
>
Not really, the two methods aren't supposed to do the same at all.
require_gem means load a gem with the name "hpricot", and then load the
library (usually .rb) files the gem's author presumes you'll want.
However, this is optional, and the gem's author can decide not to load
any files in the gem by default, and then require_gem only serves to
determine the correct version. On the contrary, it is a little weird to
me that the decision of what code from a gem you want to use is up to
its authors and not its users, and I'm not aware of there being a
"prefer this version of a gem" method that's strictly orthogonal to
"load this library". But that's digressing.
Rubygems modifies the semantics of require so that it also searches in
installed gems for a file you're trying to find. The require 'hpricot'
doesn't try to load a gem named hpricot, it tries to load file
'hpricot.rb' whether it's part of gems installed on the machine, or in
the "standard" library locations. The fact the gem names are usually
identical to names of files inside them you want to load makes this
difference hard to spot.
This manifests itself with the FOX bindings, for example: the gem name
is 'fxruby', but the file to load is 'fox16.so', and the gem doesn't
automatically load it. To wit, an irb session demonstrating the behaviour:
irb(main):001:0> $VERBOSE = nil
=> nil
irb(main):002:0> require 'rubygems'
=> true
irb(main):003:0> require 'fxruby'
LoadError: no such file to load -- fxruby
from
C:/Ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in
`gem_original_require'
from
C:/Ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'
from (irb):3
from C:/Ruby/lib/ruby/1.8/time.rb:65
irb(main):004:0> require_gem 'fxruby'
=> true
irb(main):005:0> Fox
NameError: uninitialized constant Fox
from (irb):5
from C:/Ruby/lib/ruby/1.8/time.rb:65
irb(main):006:0> require 'fox16'
=> true
irb(main):007:0> Fox
=> Fox
David Vallner