diff options
-rw-r--r-- | test/ruby/test_module.rb | 26 | ||||
-rw-r--r-- | vm.c | 2 | ||||
-rw-r--r-- | vm_method.c | 4 |
3 files changed, 30 insertions, 2 deletions
diff --git a/test/ruby/test_module.rb b/test/ruby/test_module.rb index 37045ad0d9..cf50db3374 100644 --- a/test/ruby/test_module.rb +++ b/test/ruby/test_module.rb @@ -705,6 +705,32 @@ class TestModule < Test::Unit::TestCase assert_equal(false, o.respond_to?(:bar=)) end + def test_attr_public_at_toplevel + s = Object.new + TOPLEVEL_BINDING.eval(<<-END).call(s.singleton_class) + proc do |c| + c.send(:attr_accessor, :x) + c.send(:attr, :y) + c.send(:attr_reader, :z) + c.send(:attr_writer, :w) + end + END + assert_nil s.x + s.x = 1 + assert_equal 1, s.x + + assert_nil s.y + s.instance_variable_set(:@y, 2) + assert_equal 2, s.y + + assert_nil s.z + s.instance_variable_set(:@z, 3) + assert_equal 3, s.z + + s.w = 4 + assert_equal 4, s.instance_variable_get(:@w) + end + def test_const_get_evaled c1 = Class.new c2 = Class.new(c1) @@ -1383,7 +1383,7 @@ rb_vm_cref_in_context(VALUE self, VALUE cbase) const rb_execution_context_t *ec = GET_EC(); const rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(ec, ec->cfp); const rb_cref_t *cref; - if (cfp->self != self) return NULL; + if (!cfp || cfp->self != self) return NULL; if (!vm_env_cref_by_cref(cfp->ep)) return NULL; cref = vm_get_cref(cfp->ep); if (CREF_CLASS(cref) != cbase) return NULL; diff --git a/vm_method.c b/vm_method.c index 35634d275c..da891229f8 100644 --- a/vm_method.c +++ b/vm_method.c @@ -1135,14 +1135,16 @@ rb_scope_module_func_set(void) vm_cref_set_visibility(METHOD_VISI_PRIVATE, TRUE); } +const rb_cref_t *rb_vm_cref_in_context(VALUE self, VALUE cbase); void rb_attr(VALUE klass, ID id, int read, int write, int ex) { ID attriv; rb_method_visibility_t visi; const rb_execution_context_t *ec = GET_EC(); + const rb_cref_t *cref = rb_vm_cref_in_context(klass, klass); - if (!ex) { + if (!ex || !cref) { visi = METHOD_VISI_PUBLIC; } else { |