"require" behaves differently in Rails vs vanilla Ruby?

I can "require" a file from the console but not from irb or a simple ruby script. It's not a path issue, the same file is found in both cases. So why is the module namespace an unrecognized constant sometimes and a valid module name others?

Same .rb file both times. This one works:

[chrisa@ibs-chrisa-ux1 lims_m6.6]$ script/console Loading development environment (Rails 2.3.5)

require 'aibs/hotfix/logger'

[2010-03-17 13:50:02] INFO AIBS::Hotfix::Logger initialized at module load time =>

exit

... but this one bombs with a NameError.

[chrisa@ibs-chrisa-ux1 lims_m6.6]$ irb irb(main):001:0> require 'aibs/hotfix/logger' NameError: uninitialized constant AIBS         from /home/chrisa/depot/tech/lims_m6.6/lib/aibs/hotfix/ logger.rb:1         from /local1/home/chrisa/rs_base_dev/ruby/lib/ruby/site_ruby/ 1.8/rubygems/custom_require.rb:31:in `gem_original_require'         from /local1/home/chrisa/rs_base_dev/ruby/lib/ruby/site_ruby/ 1.8/rubygems/custom_require.rb:31:in `require'         from (irb):1 irb(main):002:0> exit

I can "require" a file from the console but not from irb or a simple ruby script. It's not a path issue, the same file is found in both cases. So why is the module namespace an unrecognized constant sometimes and a valid module name others?

When you run script/console a lot more is loaded that if you just run irb (eg plugins are loaded, rails is loaded, application initializers are loaded). In addition const_missing is hooked which will automatically require stuff when a missing constant is found. Either of these could explain the difference between the two cases

Fred

Thanks for helping me understand this. I get that lots of stuff gets loaded via the console, it certainly takes longer :wink:

Here's what's really puzzling. It seems like the syntax is changing. Could this be an effect of the const_missing hook? For example, I don't even have to load a file. The console can handle the scoping on one line:

[chrisa@ibs-chrisa-ux1 lims_m6.6]$ script/console Loading development environment (Rails 2.3.5)

module AIBS::Hotfix::Logger end

=> nil

but irb can't:

[chrisa@ibs-chrisa-ux1 lims_m6.6]$ irb irb(main):001:0> module AIBS::Hotfix::Logger irb(main):002:1> end NameError: uninitialized constant AIBS         from (irb):1 irb(main):003:0> [chrisa@ibs-chrisa-ux1 lims_m6.6]$

what's even weirder, instead of the <a>::<b>::<c> form, I nest them on different lines and voila:

[chrisa@ibs-chrisa-ux1 lims_m6.6]$ irb irb(main):001:0> module AIBS irb(main):002:1> module Hotfix irb(main):003:2> module Logger irb(main):004:3> end irb(main):005:2> end irb(main):006:1> end => nil

Yikes!

This is all driven by a desire to use a bunch of (our) library code outside of the Rails framework i.e. for backend processing...

Any pointers you could suggest that would help me get a grip on what's going on would be greatly appreciated.

but irb can't:

[chrisa@ibs-chrisa-ux1 lims_m6.6]$ irb irb(main):001:0> module AIBS::Hotfix::Logger irb(main):002:1> end NameError: uninitialized constant AIBS from (irb):1 irb(main):003:0> [chrisa@ibs-chrisa-ux1 lims_m6.6]$

what's even weirder, instead of the <a>::<b>::<c> form, I nest them on different lines and voila:

That's not unexpected - the second form reopens (or creates) the AIBS module, whereas writing AIBS::Hotfix::Logger requires the AIBS and AIBS::Hotfix already exist. If they don't exist then const_missing is hit. Rails hooks this to try and load AIBS from somewhere (as long as there is a file named aibs.rb in one of the search paths this should work), apparently succeeding, whereas the default implementation just throws NameError

This is all driven by a desire to use a bunch of (our) library code outside of the Rails framework i.e. for backend processing...

The easy way here is to require config/environment which loads up rails for you. If you just want the const autoloading you can set that up to but you'll have to delve into the Rails startup stuff to see how it initializes stuff.

Fred

Ah. Thanks, this makes (more) sense now.