зеркало из https://github.com/github/ruby.git
* vm_insnhelper.c (vm_search_const_defined_class): search
ancestors only when global scope. [ruby-core:39227] [Bug #5264] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33163 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
5e14b97947
Коммит
7dddaf6807
|
@ -1,3 +1,8 @@
|
|||
Fri Sep 2 14:36:47 2011 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* vm_insnhelper.c (vm_search_const_defined_class): search
|
||||
ancestors only when global scope. [ruby-core:39227] [Bug #5264]
|
||||
|
||||
Fri Sep 2 09:58:08 2011 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* parse.y (parser_tokadd_string, parser_yylex): ignore a backslash
|
||||
|
|
10
insns.def
10
insns.def
|
@ -895,7 +895,6 @@ defineclass
|
|||
(VALUE val)
|
||||
{
|
||||
VALUE klass;
|
||||
int newclass = 1;
|
||||
|
||||
switch ((int)define_type) {
|
||||
case 0: /* scoped: class Foo::Bar */
|
||||
|
@ -904,16 +903,15 @@ defineclass
|
|||
|
||||
if (super == Qnil) {
|
||||
super = rb_cObject;
|
||||
newclass = 0;
|
||||
}
|
||||
|
||||
vm_check_if_namespace(cbase);
|
||||
|
||||
/* find klass */
|
||||
rb_autoload_load(cbase, id);
|
||||
if (vm_const_defined_at(cbase, id, newclass)) {
|
||||
if ((klass = vm_search_const_defined_class(cbase, id)) != 0) {
|
||||
/* already exist */
|
||||
klass = define_type == 0 ? rb_public_const_get(cbase, id) : rb_const_get_from(cbase, id);
|
||||
klass = define_type == 0 ? rb_public_const_get_at(klass, id) : rb_const_get_at(klass, id);
|
||||
if (TYPE(klass) != T_CLASS) {
|
||||
rb_raise(rb_eTypeError, "%s is not a class", rb_id2name(id));
|
||||
}
|
||||
|
@ -949,8 +947,8 @@ defineclass
|
|||
vm_check_if_namespace(cbase);
|
||||
|
||||
/* find klass */
|
||||
if (vm_const_defined_at(cbase, id, 0)) {
|
||||
klass = define_type == 2 ? rb_public_const_get(cbase, id) : rb_const_get_from(cbase, id);
|
||||
if ((klass = vm_search_const_defined_class(cbase, id)) != 0) {
|
||||
klass = define_type == 2 ? rb_public_const_get_at(klass, id) : rb_const_get_at(klass, id);
|
||||
/* already exist */
|
||||
if (TYPE(klass) != T_MODULE) {
|
||||
rb_raise(rb_eTypeError, "%s is not a module", rb_id2name(id));
|
||||
|
|
|
@ -548,15 +548,25 @@ class TestModule < Test::Unit::TestCase
|
|||
def test_const_in_module
|
||||
bug3423 = '[ruby-core:37698]'
|
||||
assert_in_out_err([], <<-INPUT, %w[ok], [], bug3423)
|
||||
module LangModuleSpecInObject
|
||||
module LangModuleTop
|
||||
end
|
||||
end
|
||||
include LangModuleSpecInObject
|
||||
module LangModuleTop
|
||||
end
|
||||
puts "ok" if LangModuleSpecInObject::LangModuleTop == LangModuleTop
|
||||
INPUT
|
||||
module LangModuleSpecInObject
|
||||
module LangModuleTop
|
||||
end
|
||||
end
|
||||
include LangModuleSpecInObject
|
||||
module LangModuleTop
|
||||
end
|
||||
puts "ok" if LangModuleSpecInObject::LangModuleTop == LangModuleTop
|
||||
INPUT
|
||||
|
||||
bug5264 = '[ruby-core:39227]'
|
||||
assert_in_out_err([], <<-'INPUT', [], [], bug5264)
|
||||
class A
|
||||
class X; end
|
||||
end
|
||||
class B < A
|
||||
module X; end
|
||||
end
|
||||
INPUT
|
||||
end
|
||||
|
||||
def test_class_variable_get
|
||||
|
|
|
@ -1253,15 +1253,18 @@ vm_get_cvar_base(NODE *cref)
|
|||
return klass;
|
||||
}
|
||||
|
||||
static int
|
||||
vm_const_defined_at(VALUE cbase, ID id, int newclass)
|
||||
static VALUE
|
||||
vm_search_const_defined_class(const VALUE cbase, ID id)
|
||||
{
|
||||
int ret = rb_const_defined_at(cbase, id);
|
||||
if (!ret && !newclass) {
|
||||
while ((cbase = RCLASS_SUPER(cbase)) != 0 && cbase != rb_cObject &&
|
||||
!(ret = rb_const_defined_at(cbase, id)));
|
||||
if (rb_const_defined_at(cbase, id)) return cbase;
|
||||
if (cbase == rb_cObject) {
|
||||
VALUE tmp = RCLASS_SUPER(cbase);
|
||||
while (tmp) {
|
||||
if (rb_const_defined_at(tmp, id)) return tmp;
|
||||
tmp = RCLASS_SUPER(tmp);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef USE_IC_FOR_IVAR
|
||||
|
|
Загрузка…
Ссылка в новой задаче