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
|
* eval.c: remove duplicated global variables rb_cProc and
|
||||||
rb_cBinding. [ruby-dev:30242]
|
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>
|
Thu Feb 1 20:31:41 2007 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
* variable.c (rb_cvar_set): remove warn argument.
|
* 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);
|
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
|
VALUE
|
||||||
rb_cvar_get(VALUE klass, ID id)
|
rb_cvar_get(VALUE klass, ID id)
|
||||||
{
|
{
|
||||||
VALUE value;
|
VALUE value, tmp;
|
||||||
|
|
||||||
if (RCLASS(klass)->iv_tbl && st_lookup(RCLASS(klass)->iv_tbl,id,&value)) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
tmp = klass;
|
||||||
|
CVAR_LOOKUP(&value, value);
|
||||||
rb_name_error(id,"uninitialized class variable %s in %s",
|
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 */
|
return Qnil; /* not reached */
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_cvar_defined(VALUE klass, ID id)
|
rb_cvar_defined(VALUE klass, ID id)
|
||||||
{
|
{
|
||||||
if (RCLASS(klass)->iv_tbl && st_lookup(RCLASS(klass)->iv_tbl,id,0)) {
|
if (!klass) return Qfalse;
|
||||||
return Qtrue;
|
CVAR_LOOKUP(0,Qtrue);
|
||||||
}
|
|
||||||
return Qfalse;
|
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);
|
NODE *cref = get_cref(iseq, th->cfp->lfp);
|
||||||
VALUE klass = Qnil;
|
VALUE klass = Qnil;
|
||||||
|
|
||||||
while (cref) {
|
if (cref) {
|
||||||
klass = cref->nd_clss;
|
klass = cref->nd_clss;
|
||||||
cref = cref->nd_next;
|
if (!cref->nd_next) {
|
||||||
|
rb_warn("class variable access from toplevel");
|
||||||
if (cref == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)) {
|
if (NIL_P(klass)) {
|
||||||
rb_raise(rb_eTypeError, "no class variables available");
|
rb_raise(rb_eTypeError, "no class variables available");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue