mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05: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
16
ChangeLog
16
ChangeLog
|
@ -12,6 +12,22 @@ Fri Feb 2 18:27:54 2007 Yukihiro Matsumoto <matz@ruby-lang.org>
|
|||
* eval.c: remove duplicated global variables rb_cProc and
|
||||
rb_cBinding. [ruby-dev:30242]
|
||||
|
||||
Thu Feb 1 20:53:32 2007 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* 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.
|
||||
|
||||
Thu Feb 1 20:31:41 2007 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* variable.c (rb_cvar_set): remove warn argument.
|
||||
|
|
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;
|
||||
}
|
||||
|
||||
|
|
17
vm.c
17
vm.c
|
@ -1141,22 +1141,11 @@ eval_get_cvar_base(yarv_thread_t *th, yarv_iseq_t *iseq)
|
|||
NODE *cref = get_cref(iseq, th->cfp->lfp);
|
||||
VALUE klass = Qnil;
|
||||
|
||||
while (cref) {
|
||||
if (cref) {
|
||||
klass = cref->nd_clss;
|
||||
cref = cref->nd_next;
|
||||
|
||||
if (cref == 0) {
|
||||
continue;
|
||||
if (!cref->nd_next) {
|
||||
rb_warn("class variable access from toplevel");
|
||||
}
|
||||
|
||||
if (NIL_P(klass) || FL_TEST(klass, FL_SINGLETON)) {
|
||||
if (cref->nd_next == 0) {
|
||||
rb_warn
|
||||
("class variable access from toplevel singleton method");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (NIL_P(klass)) {
|
||||
rb_raise(rb_eTypeError, "no class variables available");
|
||||
|
|
Loading…
Add table
Reference in a new issue