summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--test/ruby/test_module.rb4
-rw-r--r--variable.c10
3 files changed, 18 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index cbd3607497..a30e2a1f84 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Sat Jan 29 01:36:41 2011 Yusuke Endoh <mame@tsg.ne.jp>
+
+ * variable.c (rb_const_set): const_set shoud preserve constant
+ visibility. see [ruby-core:32912].
+
+ * test/ruby/test_module.rb: add a test for above.
+
Sat Jan 29 01:24:57 2011 Yusuke Endoh <mame@tsg.ne.jp>
* compile.c (NODE_CLASS, NODE_MODULE), insns.def (defineclass): raise
diff --git a/test/ruby/test_module.rb b/test/ruby/test_module.rb
index 3306c0db74..e3b433e2cb 100644
--- a/test/ruby/test_module.rb
+++ b/test/ruby/test_module.rb
@@ -948,6 +948,10 @@ class TestModule < Test::Unit::TestCase
assert_raise(NameError) { c::FOO }
assert_equal("foo", c.class_eval("FOO"))
assert_equal("foo", c.const_get("FOO"))
+ $VERBOSE, verbose = nil, $VERBOSE
+ c.const_set(:FOO, "foo")
+ $VERBOSE = verbose
+ assert_raise(NameError) { c::FOO }
end
class PrivateClass
diff --git a/variable.c b/variable.c
index 1f4cf76fae..1ee299e358 100644
--- a/variable.c
+++ b/variable.c
@@ -1876,6 +1876,7 @@ void
rb_const_set(VALUE klass, ID id, VALUE val)
{
rb_const_entry_t *ce;
+ VALUE visibility = CONST_PUBLIC;
if (NIL_P(klass)) {
rb_raise(rb_eTypeError, "no class/module to define constant %s",
@@ -1890,17 +1891,20 @@ rb_const_set(VALUE klass, ID id, VALUE val)
st_data_t value;
if (st_lookup(RCLASS_CONST_TBL(klass), (st_data_t)id, &value)) {
- if (((rb_const_entry_t*)value)->value == Qundef)
+ rb_const_entry_t *ce = (rb_const_entry_t*)value;
+ if (ce->value == Qundef)
autoload_delete(klass, id);
- else
+ else {
+ visibility = ce->flag;
rb_warn("already initialized constant %s", rb_id2name(id));
+ }
}
}
rb_vm_change_state();
ce = ALLOC(rb_const_entry_t);
- ce->flag = CONST_PUBLIC;
+ ce->flag = visibility;
ce->value = val;
st_insert(RCLASS_CONST_TBL(klass), (st_data_t)id, (st_data_t)ce);