From: Josh Cheek Date: 2011-06-11T23:16:44+09:00 Subject: Re: a little challenge - reproduce this error --90e6ba53ac34acb9af04a57055ae Content-Type: text/plain; charset=ISO-8859-1 On Sat, Jun 11, 2011 at 8:36 AM, Intransition wrote: > > > On Jun 10, 2:52 pm, Intransition wrote: > > On Jun 10, 1:19 pm, Josh Cheek wrote: > > > > > Well, I give up :) > > > > I bet a few people have come across it without fully knowing what was > > going on and just fixed their issue by adding `::` to the "X". That's > > what I did a few times before I realized what the hell was going on. > > > > The change needed to cause the error is this: > > > > module X > > class Foo < BasicObject > > def call > > X > > end > > end > > end > > > > Right off you can see this only effect Ruby 1.9+ (b/c 1.8 has no > > BasicObject). > > > > Next up... why it happens and how to fix. > > Ok, so the fix to this problem is... #const_missing: > > module X > class Foo < BasicObject > def call > X > end > def self.const_missing(const) > Object.const_get(const) > end > end > end > > Which tells us why we get the error in the first place. Toplevel > constants, like toplevel instance methods, are defined on Object > itself -- the toplevel (aka `main`) is (mostly) just a proxy for > Object. And since BasicObject doesn't inherit from Object like every > other object in Ruby's universe, it can't find, in this case, module > X. > > So that's the deal. If you ever run into this, you now know what to > do. > > Fascinating stuff! > SIDE NOTE: I'm pretty sure that toplevel should not be a proxy of > object. And that constant look up should terminate with the toplevel > (just after Object) rather than with the Object class. A big benefit > from this would be the ability eval scripts at the toplevel instead of > in a protected module that emulated the toplevel (yet another proxy) > in order to prevent method definitions from polluting every object. I > mean think about that --every object. Talk about your monkey patching! > I've mentioned this to matz before, and while he's never said as much, > i'm hopeful that Ruby 2.0 (whenever that might arrive) will take the > idea to heart. > > I could see that. I already avoid defining toplevel methods, but when I do make them, I usually make them on main's singleton class (unless, of course, it really does need to be globally callable). > P.S. In my attempt to "quizify" this Ruby quirk, I have to say, James > Edward Gray II, I am humbled! :-) > > lol. --90e6ba53ac34acb9af04a57055ae--