mirror of
https://github.com/ruby/ruby.git
synced 2025-08-15 21:49:06 +02:00
* vm.c (eval_get_cvar_base): destination for class variable access
is now strictly innermost surrounding class or module. warned if accessed from toplevel. * variable.c (rb_cvar_get): new class variable look-up scheme: 1) look up in the class. 2) if the class is singleton attached to a class (i.e. metaclass) then start look up in the attached class and its ancestors. 3) otherwise, look-up in ancestors of the class. * eval.c (cvar_cbase): destination for class variable access is the class/module that holds the method, or cbase outside of methods. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11613 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
e137ee9ac4
commit
d99bcbe583
3 changed files with 52 additions and 23 deletions
42
variable.c
42
variable.c
|
@ -1570,26 +1570,50 @@ rb_cvar_set(VALUE klass, ID id, VALUE val)
|
|||
mod_av_set(klass, id, val, Qfalse);
|
||||
}
|
||||
|
||||
#define CVAR_LOOKUP(v,r) do {\
|
||||
if (RCLASS(klass)->iv_tbl && st_lookup(RCLASS(klass)->iv_tbl,id,(v))) {\
|
||||
return (r);\
|
||||
}\
|
||||
if (FL_TEST(klass, FL_SINGLETON) ) {\
|
||||
VALUE obj = rb_iv_get(klass, "__attached__");\
|
||||
switch (TYPE(obj)) {\
|
||||
case T_MODULE:\
|
||||
case T_CLASS:\
|
||||
klass = obj;\
|
||||
break;\
|
||||
default:\
|
||||
klass = RCLASS(klass)->super;\
|
||||
break;\
|
||||
}\
|
||||
}\
|
||||
else {\
|
||||
klass = RCLASS(klass)->super;\
|
||||
}\
|
||||
while (klass) {\
|
||||
if (RCLASS(klass)->iv_tbl && st_lookup(RCLASS(klass)->iv_tbl,id,(v))) {\
|
||||
return (r);\
|
||||
}\
|
||||
klass = RCLASS(klass)->super;\
|
||||
}\
|
||||
} while(0)
|
||||
|
||||
VALUE
|
||||
rb_cvar_get(VALUE klass, ID id)
|
||||
{
|
||||
VALUE value;
|
||||
|
||||
if (RCLASS(klass)->iv_tbl && st_lookup(RCLASS(klass)->iv_tbl,id,&value)) {
|
||||
return value;
|
||||
}
|
||||
VALUE value, tmp;
|
||||
|
||||
tmp = klass;
|
||||
CVAR_LOOKUP(&value, value);
|
||||
rb_name_error(id,"uninitialized class variable %s in %s",
|
||||
rb_id2name(id), rb_class2name(klass));
|
||||
rb_id2name(id), rb_class2name(tmp));
|
||||
return Qnil; /* not reached */
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_cvar_defined(VALUE klass, ID id)
|
||||
{
|
||||
if (RCLASS(klass)->iv_tbl && st_lookup(RCLASS(klass)->iv_tbl,id,0)) {
|
||||
return Qtrue;
|
||||
}
|
||||
if (!klass) return Qfalse;
|
||||
CVAR_LOOKUP(0,Qtrue);
|
||||
return Qfalse;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue