diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | proc.c | 8 | ||||
-rw-r--r-- | test/ruby/test_method.rb | 32 |
3 files changed, 44 insertions, 1 deletions
@@ -1,3 +1,8 @@ +Sun Mar 31 17:17:56 2013 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * proc.c (rb_mod_define_method): consider visibility in define_method. + patch by mashiro <mail AT mashiro.org>. fix GH-268. + Sun Mar 31 15:40:30 2013 Nobuyoshi Nakada <nobu@ruby-lang.org> * win32/configure.bat: try to fix option arguments split by commas and @@ -1377,7 +1377,7 @@ rb_mod_define_method(int argc, VALUE *argv, VALUE mod) { ID id; VALUE body; - int noex = NOEX_PUBLIC; + int noex = (int)rb_vm_cref()->nd_visi; if (argc == 1) { id = rb_to_id(argv[0]); @@ -1410,6 +1410,9 @@ rb_mod_define_method(int argc, VALUE *argv, VALUE mod) } } rb_method_entry_set(mod, id, method->me, noex); + if (noex == NOEX_MODFUNC) { + rb_method_entry_set(rb_singleton_class(mod), id, method->me, NOEX_PUBLIC); + } } else if (rb_obj_is_proc(body)) { rb_proc_t *proc; @@ -1423,6 +1426,9 @@ rb_mod_define_method(int argc, VALUE *argv, VALUE mod) proc->block.klass = mod; } rb_add_method(mod, id, VM_METHOD_TYPE_BMETHOD, (void *)body, noex); + if (noex == NOEX_MODFUNC) { + rb_add_method(rb_singleton_class(mod), id, VM_METHOD_TYPE_BMETHOD, (void *)body, NOEX_PUBLIC); + } } else { /* type error */ diff --git a/test/ruby/test_method.rb b/test/ruby/test_method.rb index c1dbd9f35f..655fac5d3b 100644 --- a/test/ruby/test_method.rb +++ b/test/ruby/test_method.rb @@ -270,6 +270,38 @@ class TestMethod < Test::Unit::TestCase assert_equal(:meth, c.new.meth, feature4254) end + def test_define_method_visibility + c = Class.new do + public + define_method(:foo) {:foo} + protected + define_method(:bar) {:bar} + private + define_method(:baz) {:baz} + end + + assert_equal(true, c.public_method_defined?(:foo)) + assert_equal(false, c.public_method_defined?(:bar)) + assert_equal(false, c.public_method_defined?(:baz)) + + assert_equal(false, c.protected_method_defined?(:foo)) + assert_equal(true, c.protected_method_defined?(:bar)) + assert_equal(false, c.protected_method_defined?(:baz)) + + assert_equal(false, c.private_method_defined?(:foo)) + assert_equal(false, c.private_method_defined?(:bar)) + assert_equal(true, c.private_method_defined?(:baz)) + + m = Module.new do + module_function + define_method(:foo) {:foo} + end + assert_equal(true, m.respond_to?(:foo)) + assert_equal(false, m.public_method_defined?(:foo)) + assert_equal(false, m.protected_method_defined?(:foo)) + assert_equal(true, m.private_method_defined?(:foo)) + end + def test_super_in_proc_from_define_method c1 = Class.new { def m |