Hi -- On Sun, 5 Mar 2006, Dominik Bathon wrote: > But actually it's even more complicated (continuing your code): > > $obj=obj > class Object > class << $obj > def i > puts X > end > end > end > > obj.i #=>top-level > > This is because the constant lookup first checks in all the outer lexical > scopes if the constant is directly defined in one of the classes and then > does a full const_get on the innermost class. So in this case, the following > happens: > > 1. Does #<Class:#<D:0xb7f3bda0>> (without ancestors) have a constant X => no > 2. Does Object (without ancestors) have a constant X => yes => constant found > > If step 2 wouldn't have found the constant then ruby would have checked the > ancestors of #<Class:#<D:0xb7f3bda0>> for the constant: > > class D > Y = "D::Y" > end > > class Object > class << $obj > def j > puts Y > end > end > end > > obj.j #=>D::Y > > Here the following happens: > > 1. Does #<Class:#<D:0xb7f3bda0>> (without ancestors) have a constant Y => no > 2. Does Object (without ancestors) have a constant Y => no > 3. Does #<Class:#<D:0xb7f3bda0>> (including ancestors) have a constant Y => > yes => constant found But Object is always an ancestor, so you don't need step 2. Also, step 2 (lookup in Object) doesn't really happen second; for example, if you put yourself in D context, the lookup will hit D::X before it hits Object::X: $obj=obj class Object class D class << $obj def k puts X end end end end obj.k # class-level So the resolution path is: #<Class:#<D...>> D # X found here Object # X exists here but not reached As I understand it, some of this is determined quasi-statically... though not the singleton class parts, since those can't be determined at all until runtime. David -- David A. Black (dblack / wobblini.net) Ruby Power and Light (http://www.rubypowerandlight.com) "Ruby for Rails" chapters now available from Manning Early Access Program! http://www.manning.com/books/black