On Friday 19 March 2010 11:23:37 am Lars Gierth wrote:
> Lars Gierth wrote:
> > I'm playing with FakeFS and want to fake Kernel#require.
> 
> Hi again, I git this working by overwriting #const_missing?, #autoload?
> and #autoload.

You probably didn't.

One example I know where Kernel#autoload works and const_missing doesn't is 
when defining a const. For example:

irb(main):001:0> autoload :CSV, 'csv'
=> nil
irb(main):002:0> module CSV
irb(main):003:1> end
TypeError: CSV is not a module
        from (irb):2
        from /home/ruby19/bin/irb:12:in `<main>'

The obvious danger here is when you try monkeypatching something first, and 
then using it:

autoload :CSV, 'csv'
class CSV
  def foo
    # ...
  end
end

With a real Kernel#autoload, that class definition will be referring to CSV, 
and actually autoload the file first, so you'll be extending CSV. With this 
one, it won't, because neither of the examples above will ever hit 
const_missing, or anything else I know of that the application can override.

This is why we need to actually need to have Kernel#autoload behave properly 
with an overridden Kernel#require, or at least have enough primitives exposed 
that we can redefine Kernel#autoload. At the moment, the _only_ option is to 
override $:, which only makes sense if you're _always_ going to autoload a 
file, as opposed to a URL, an expression, or anything else.

This has apparently been known about for years. It's one of two fairly brain-
dead decisions I've seen the Ruby language make, and unfortunately, is the 
kind of problem that can really only be fixed by hacking on the interpreter 
itself.