ruby-changes:24523
From: nobu <ko1@a...>
Date: Mon, 30 Jul 2012 14:24:34 +0900 (JST)
Subject: [ruby-changes:24523] nobu:r36574 (trunk): variable.c: tmp_classpath
nobu 2012-07-30 14:24:24 +0900 (Mon, 30 Jul 2012) New Revision: 36574 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=36574 Log: variable.c: tmp_classpath * variable.c: store anonymous class path in tmp_classpath but not in classpath. [ruby-core:42865][Bug #6078] Modified files: trunk/ChangeLog trunk/test/ruby/test_module.rb trunk/variable.c Index: ChangeLog =================================================================== --- ChangeLog (revision 36573) +++ ChangeLog (revision 36574) @@ -1,3 +1,8 @@ +Mon Jul 30 14:24:20 2012 Nobuyoshi Nakada <nobu@r...> + + * variable.c: store anonymous class path in tmp_classpath but not in + classpath. [ruby-core:42865][Bug #6078] + Mon Jul 30 13:11:54 2012 Nobuyoshi Nakada <nobu@r...> * configure.in (DLDFLAGS): on Darwin, deprecate -flat_namespace to get Index: variable.c =================================================================== --- variable.c (revision 36573) +++ variable.c (revision 36574) @@ -35,7 +35,7 @@ } struct fc_result { - ID name; + ID name, preferred; VALUE klass; VALUE path; VALUE track; @@ -78,7 +78,7 @@ VALUE value = ce->value; if (!rb_is_const_id(key)) return ST_CONTINUE; - if (value == res->klass) { + if (value == res->klass && (!res->preferred || key == res->preferred)) { res->path = fc_path(res, key); return ST_STOP; } @@ -95,6 +95,7 @@ } arg.name = key; + arg.preferred = res->preferred; arg.path = 0; arg.klass = res->klass; arg.track = value; @@ -110,10 +111,12 @@ } static VALUE -find_class_path(VALUE klass) +find_class_path(VALUE klass, ID preferred) { struct fc_result arg; + find: + arg.preferred = preferred; arg.name = 0; arg.path = 0; arg.klass = klass; @@ -134,6 +137,10 @@ st_delete(RCLASS_IV_TBL(klass), &tmp, 0); return arg.path; } + if (preferred) { + preferred = 0; + goto find; + } return Qnil; } @@ -147,9 +154,14 @@ if (RCLASS_IV_TBL(klass)) { if (!st_lookup(RCLASS_IV_TBL(klass), (st_data_t)classpath, &n)) { if (!st_lookup(RCLASS_IV_TBL(klass), (st_data_t)classid, &n)) { - return find_class_path(klass); + return find_class_path(klass, (ID)0); } - path = rb_str_dup(rb_id2str(SYM2ID((VALUE)n))); + path = find_class_path(klass, SYM2ID(n)); + if (NIL_P(path)) { + path = rb_str_dup(rb_id2str(SYM2ID((VALUE)n))); + OBJ_FREEZE(path); + return path; + } OBJ_FREEZE(path); st_insert(RCLASS_IV_TBL(klass), (st_data_t)classpath, (st_data_t)path); n = classid; @@ -163,7 +175,7 @@ } return path; } - return find_class_path(klass); + return find_class_path(klass, (ID)0); } /* @@ -182,15 +194,19 @@ return path; } -VALUE -rb_class_path(VALUE klass) +static VALUE +rb_tmp_class_path(VALUE klass, int *permanent) { VALUE path = classname(klass); st_data_t n = (st_data_t)path; - if (!NIL_P(path)) return path; + if (!NIL_P(path)) { + *permanent = 1; + return path; + } if (RCLASS_IV_TBL(klass) && st_lookup(RCLASS_IV_TBL(klass), (st_data_t)tmp_classpath, &n)) { + *permanent = 0; return (VALUE)n; } else { @@ -207,11 +223,19 @@ path = rb_sprintf("#<%s:%p>", s, (void*)klass); OBJ_FREEZE(path); rb_ivar_set(klass, tmp_classpath, path); + *permanent = 0; return path; } } +VALUE +rb_class_path(VALUE klass) +{ + int permanent; + return rb_tmp_class_path(klass, &permanent); +} + void rb_set_class_path_string(VALUE klass, VALUE under, VALUE name) { @@ -221,10 +245,12 @@ str = rb_str_new_frozen(name); } else { - str = rb_str_dup(rb_class_path(under)); + int permanent; + str = rb_str_dup(rb_tmp_class_path(under, &permanent)); rb_str_cat2(str, "::"); rb_str_append(str, name); OBJ_FREEZE(str); + if (!permanent) return; } rb_ivar_set(klass, classpath, str); } @@ -233,16 +259,18 @@ rb_set_class_path(VALUE klass, VALUE under, const char *name) { VALUE str; + int permanent = 1; if (under == rb_cObject) { str = rb_str_new2(name); } else { - str = rb_str_dup(rb_class_path(under)); + str = rb_str_dup(rb_tmp_class_path(under, &permanent)); rb_str_cat2(str, "::"); rb_str_cat2(str, name); } OBJ_FREEZE(str); + if (!permanent) return; rb_ivar_set(klass, classpath, str); } Index: test/ruby/test_module.rb =================================================================== --- test/ruby/test_module.rb (revision 36573) +++ test/ruby/test_module.rb (revision 36574) @@ -363,6 +363,23 @@ assert_equal("TestModule::User", User.name) end + def test_classpath + m = Module.new + n = Module.new + m.const_set(:N, n) + assert_nil(m.name) + assert_nil(n.name) + assert_equal([:N], m.constants) + m.module_eval("module O end") + assert_equal([:N, :O], m.constants) + assert_nil(m::N.name) + assert_match(/\A(?:#<Module:.*>::)?O\z/, m::O.name) + self.class.const_set(:M, m) + prefix = self.class.name + "::M::" + assert_equal(prefix+"N", m.const_get(:N).name) + assert_equal(prefix+"O", m.const_get(:O).name) + end + def test_private_class_method assert_raise(ExpectedException) { AClass.cm1 } assert_raise(ExpectedException) { AClass.cm3 } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/