From: Nobuyoshi Nakada Date: 2011-01-10T14:54:53+09:00 Subject: [ruby-core:34290] Re: [Ruby 1.9-Feature#4254][Open] Allow method transplanting Hi, At Mon, 10 Jan 2011 10:14:34 +0900, Yukihiro Matsumoto wrote in [ruby-core:34283]: > No, I am thinking of methods defined for modules, that have no > assumption of the type of receivers. Ruby methods in C does not check > the type of the receiver, so that if you move a method from String > class to, say, Array, the interpreter will crash when you call the > transplanted method. Just between modules? * proc.c (rb_mod_define_method): allow method transplanting between modules. [ruby-core:34267] diff --git i/proc.c w/proc.c index 9ecf626..6affba6 100644 --- i/proc.c +++ w/proc.c @@ -1303,7 +1303,8 @@ rb_mod_define_method(int argc, VALUE *argv, VALUE mod) if (rb_obj_is_method(body)) { struct METHOD *method = (struct METHOD *)DATA_PTR(body); VALUE rclass = method->rclass; - if (rclass != mod && !RTEST(rb_class_inherited_p(mod, rclass))) { + if (rclass != mod && !(RB_TYPE_P(rclass, T_MODULE) && RB_TYPE_P(mod, T_MODULE)) && + !RTEST(rb_class_inherited_p(mod, rclass))) { if (FL_TEST(rclass, FL_SINGLETON)) { rb_raise(rb_eTypeError, "can't bind singleton method to a different class"); diff --git i/test/ruby/test_method.rb w/test/ruby/test_method.rb index fa5f998..0cbc785 100644 --- i/test/ruby/test_method.rb +++ w/test/ruby/test_method.rb @@ -36,7 +36,7 @@ class TestMethod < Test::Unit::TestCase module M def func; end module_function :func - def meth; end + def meth; :meth end end def mv1() end @@ -205,6 +205,11 @@ class TestMethod < Test::Unit::TestCase assert_raise(TypeError) do Class.new.class_eval {define_method(:meth, M.instance_method(:meth))} end + + feature4254 = '[ruby-core:34267]' + m = Module.new + m.module_eval {define_method(:meth, M.instance_method(:meth))} + assert_equal(:meth, Object.new.extend(m).meth, feature4254) end def test_clone -- Nobu Nakada