From: David Masover Date: 2010-03-20T04:33:25+09:00 Subject: Re: Kernel#autoload ignores custom monkey patched Kernel#require 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 `
' 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.