Hi -- On Mon, 6 Mar 2006, Dominik Bathon wrote: > On Sun, 05 Mar 2006 20:01:49 +0100, <dblack / wobblini.net> wrote: > >> Hi -- >> >> On Sun, 5 Mar 2006, Dominik Bathon wrote: >> >>> 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. > > Yes, but these are the steps that ruby (1.8.4) does when looking up the > constants, here is the code (eval.c): > > static VALUE > ev_const_get(cref, id, self) > NODE *cref; > ID id; > VALUE self; > { > NODE *cbase = cref; > VALUE result; > > while (cbase && cbase->nd_next) { > VALUE klass = cbase->nd_clss; > > if (NIL_P(klass)) return rb_const_get(CLASS_OF(self), id); > while (RCLASS(klass)->iv_tbl && st_lookup(RCLASS(klass)->iv_tbl, id, > &result)) { > if (result == Qundef) { > if (!RTEST(rb_autoload_load(klass, id))) break; > continue; > } > return result; > } > cbase = cbase->nd_next; > } > return rb_const_get(cref->nd_clss, id); > } > > The while loop checks if the constant is defined directly (without ancestors) > in one of the enclosing classes, and finally if the while loop doesn't find > the constant ruby does a full rb_const_get() on the innermost class (which > includes the ancestors). I think I was misunderstanding the relation between your example and your explanation. If I'm (now) right, you were just using Object as an example of an enclosing class. I had thought you were saying that Object itself always gets checked before the ancestors. >> 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. > > You can think of it as happening "quasi-statically", but actually class, > module and "class <<" are executed almost identically by the interpreter > (only different "preparations"). I mean constant resolution specifically. But I may be behind the times. 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