Hi --

On Fri, 11 Jul 2008, Tilman Giese wrote:

> Hi,
>
> I am stuck in some constant lookup behavior and I would really appreciate if 
> someone could enlighten me what is going on. Here is the example:
>
> <snippet>
>
> class A
>
> class << self
>   class B
>   end
>
>   def testme1
>     puts B # prints #<Class:0xac6598>::B
>   end
> end
>
> def self.testme2
>   puts B # raises a NameError
> end
>
> end
>
> A.testme1
> A.testme2
>
> </snippet>
>
> I do not understand why those two class methods behave differently depending 
> on how they were defined. It looks very confusing to me. Or is there an 
> important reason for that? How does the constant lookup work in both 
> examples?

It's not just class methods. This is (I think) the one difference
between the two ways of creating a singleton method in general.


   A = "Outer A"
   obj = Object.new

   class << obj
     A = "Singleton class A"
     def a
       puts A
     end
   end

   def obj.a2
     puts A
   end

   obj.a      # Singleton class A
   obj.a2     # Outer A

def obj.a2 doesn't open a class definition body, and constants belong
to classes and modules. So when the resolution logic looks "up", the
first thing it sees above the level of the method definition body is
the outer scope, so that's where it looks for A.

It's part of quasi-static resolution of constants. Here's another
case:

   X = 1
   class A
     class B
       X = 2
       class C
         puts X       # 2
       end
     end
   end

   class A::B::C
     puts X           # 1
   end

The A::B::C notation does open that class body, but it compresses the
nesting in such a way that the resolution logic just skips over it in
one step and lands in the outer scope, where X is 1.


David

-- 
Rails training from David A. Black and Ruby Power and Light:
   Intro to Ruby on Rails  July 21-24      Edison, NJ
   Advancing With Rails    August 18-21    Edison, NJ
See http://www.rubypal.com for details and updates!