diff options
author | Koichi Sasada <[email protected]> | 2024-10-31 19:08:05 +0900 |
---|---|---|
committer | Koichi Sasada <[email protected]> | 2024-11-01 11:50:00 +0900 |
commit | 783dde2159a3689ad2d3ef6b7d0005a7cf80adba (patch) | |
tree | 1f7392e25cc008826be38a5736da4633a6c5fe3a | |
parent | a8c32ace459d56501c03e360da7c315d5b91142a (diff) |
`alias` should not set `defined_class` for Modules
`me->defined_class` should be 0 for method entries of
Modules.
This patch checks this condition
and fix https://github.com/ruby/ruby/pull/11965#issuecomment-2448291790
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/11968
-rw-r--r-- | test/ruby/test_alias.rb | 36 | ||||
-rw-r--r-- | vm_method.c | 8 |
2 files changed, 43 insertions, 1 deletions
diff --git a/test/ruby/test_alias.rb b/test/ruby/test_alias.rb index 0d33cb993c..6d4fcc085b 100644 --- a/test/ruby/test_alias.rb +++ b/test/ruby/test_alias.rb @@ -292,4 +292,40 @@ class TestAlias < Test::Unit::TestCase end end; end + + def test_alias_complemented_method + assert_in_out_err(%w[-w], "#{<<~"begin;"}\n#{<<~'end;'}") + begin; + module M + def foo = 1 + self.extend M + end + + 3.times{|i| + module M + alias foo2 foo + remove_method :foo + def foo = 2 + ensure + remove_method :foo + alias foo foo2 + remove_method :foo2 + end + + M.foo + + original_foo = M.method(:foo) + + M.class_eval do + remove_method :foo + def foo = 3 + end + + M.class_eval do + remove_method :foo + define_method :foo, original_foo + end + } + end; + end end diff --git a/vm_method.c b/vm_method.c index 1a6e965e44..120e8b0563 100644 --- a/vm_method.c +++ b/vm_method.c @@ -2332,7 +2332,13 @@ rb_alias(VALUE klass, ID alias_name, ID original_name) alias_me = method_entry_set(target_klass, alias_name, orig_me, visi, orig_me->owner); RB_OBJ_WRITE(alias_me, &alias_me->owner, target_klass); - RB_OBJ_WRITE(alias_me, &alias_me->defined_class, orig_me->defined_class); + + if (RB_TYPE_P(target_klass, T_MODULE)) { + // defined_class should not be set + } + else { + RB_OBJ_WRITE(alias_me, &alias_me->defined_class, orig_me->defined_class); + } } } |