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