From: Stephen Prater Date: 2011-04-22T06:34:21+09:00 Subject: Re: class_eval doesn't find const_missing http://stackoverflow.com/questions/3015947/ruby-how-does-constant-lookup-work-in-instance-eval-class-eval Const lookup varies between 1.8, 1.9.1, and 1.9.2. Basically, constants are lexically scoped. You can use "const_get" I believe to lookup your constant in the current binding rather than in the lexical scope. stephen On Apr 21, 2011, at 2:20 PM, Andrew Berkeley wrote: > I am trying to write a DSL which uses method_missing and const_missing > to catch upper and lowercase names (specified in isolation) and fetch > the asscoated (already initialized) objects. This works great until I > need to use class_eval which seemingly doesn't follow the custom > const_missing method. > > Here's a more simple example of a class with a constant and > #method_missing and #const_missing methods. > > class DummyClass > > NAME = 'dummy constant' > > def self.method_missing(method,*args,&block) > return "this #{method} was captured by #method_missing" > end > > def self.const_missing(constant) > return "this #{constant} was captured by #const_missing" > end > > end > > Accessing the constant is no problem >> DummyClass::NAME > => "dummy constant" > > Unknown methods and constants are handled as expected >> DummyClass::ANOTHER_CONSTANT > => "this ANOTHER_CONSTANT was captured by #const_missing" >> DummyClass.some_method > => "this some_method was captured by #method_missing" > > Accessing the constant via class_eval is variable - it works when > evaluating strings but not blocks. >> DummyClass.class_eval "NAME" > => "dummy constant" >> DummyClass.class_eval {NAME} > NameError: uninitialized constant NAME > from (irb):14 > from (irb):14:in `class_eval' > from (irb):14 > from :0 > > This is partly understood since blocks are scoped to the context in > which they were created. But even if the explicit constant is not > recognised, why isn't the class #const_missing method invoked? > > Does the class_eval method allow the method_missing method to be used? >> DummyClass.class_eval "dummy_method" > => "this dummy_method was captured by #method_missing" >> DummyClass.class_eval {dummy_method} > => "this dummy_method was captured by #method_missing" > > Yes. #method_missing works as expected, in both string and block > formats. So only #const_missing is causing a problem. > > Interestingly, an explicit call to #const_missing inside a class_eval > block DOES work. >> DummyClass.class_eval {const_missing :ANOTHER_CONSTANT} > => "this ANOTHER_CONSTANT was captured by #const_missing" > > Anybody understand this, and is there a way to get around it? > > Cheers > > -- > Posted via http://www.ruby-forum.com/. > >