diff options
| -rw-r--r-- | proc.c | 2 | ||||
| -rw-r--r-- | spec/ruby/core/unboundmethod/equal_value_spec.rb | 30 | ||||
| -rw-r--r-- | spec/ruby/core/unboundmethod/fixtures/classes.rb | 16 | ||||
| -rw-r--r-- | test/ruby/test_method.rb | 14 |
4 files changed, 62 insertions, 0 deletions
@@ -1844,6 +1844,8 @@ method_eq(VALUE method, VALUE other) klass1 = method_entry_defined_class(m1->me); klass2 = method_entry_defined_class(m2->me); + if (RB_TYPE_P(klass1, T_ICLASS)) klass1 = RBASIC_CLASS(klass1); + if (RB_TYPE_P(klass2, T_ICLASS)) klass2 = RBASIC_CLASS(klass2); if (!rb_method_entry_eq(m1->me, m2->me) || klass1 != klass2 || diff --git a/spec/ruby/core/unboundmethod/equal_value_spec.rb b/spec/ruby/core/unboundmethod/equal_value_spec.rb index 036c6b7f8c..a9d79f1484 100644 --- a/spec/ruby/core/unboundmethod/equal_value_spec.rb +++ b/spec/ruby/core/unboundmethod/equal_value_spec.rb @@ -35,6 +35,12 @@ describe "UnboundMethod#==" do @method_one = UnboundMethodSpecs::Methods.instance_method(:one) @method_two = UnboundMethodSpecs::Methods.instance_method(:two) + + @mixin = UnboundMethodSpecs::Mixin.instance_method(:mixin_method) + @includer_base = UnboundMethodSpecs::IncluderBase.new.method(:mixin_method).unbind + @includer_child = UnboundMethodSpecs::IncluderChild.new.method(:mixin_method).unbind + @extender_base = UnboundMethodSpecs::ExtenderBase.method(:mixin_method).unbind + @extender_child = UnboundMethodSpecs::ExtenderChild.method(:mixin_method).unbind end it "returns true if objects refer to the same method" do @@ -110,6 +116,30 @@ describe "UnboundMethod#==" do end end + ruby_bug "#21873", ""..."3.4" do + it "returns true if same method is present in an object through module inclusion" do + (@mixin == @includer_base).should == true + (@includer_base == @mixin).should == true + + (@mixin == @includer_child).should == true + (@includer_child == @mixin).should == true + + (@includer_base == @includer_child).should == true + (@includer_child == @includer_base).should == true + end + + it "returns true if same method is present in an object through module extension" do + (@mixin == @extender_base).should == true + (@extender_base == @mixin).should == true + + (@mixin == @extender_child).should == true + (@extender_child == @mixin).should == true + + (@extender_base == @extender_child).should == true + (@extender_child == @extender_base).should == true + end + end + it "returns false if both have same Module, same name, identical body but not the same" do class UnboundMethodSpecs::Methods def discard_1; :discard; end diff --git a/spec/ruby/core/unboundmethod/fixtures/classes.rb b/spec/ruby/core/unboundmethod/fixtures/classes.rb index 28d8e0a965..bb3f7e0849 100644 --- a/spec/ruby/core/unboundmethod/fixtures/classes.rb +++ b/spec/ruby/core/unboundmethod/fixtures/classes.rb @@ -80,6 +80,22 @@ module UnboundMethodSpecs end end + module Mixin + def mixin_method; end + end + + class IncluderBase + include Mixin + end + + class IncluderChild < IncluderBase; end + + class ExtenderBase + extend Mixin + end + + class ExtenderChild < ExtenderBase; end + class A def baz(a, b) return [__FILE__, self.class] diff --git a/test/ruby/test_method.rb b/test/ruby/test_method.rb index a865f6100b..27765577c7 100644 --- a/test/ruby/test_method.rb +++ b/test/ruby/test_method.rb @@ -111,6 +111,20 @@ class TestMethod < Test::Unit::TestCase end end + def test_unbound_method_equality_with_extended_module + m = Module.new { def hello; "hello"; end } + base = Class.new { extend m } + sub = Class.new(base) + + from_module = m.instance_method(:hello) + from_base = base.method(:hello).unbind + from_sub = sub.method(:hello).unbind + + assert_equal(from_module, from_base) + assert_equal(from_module, from_sub) + assert_equal(from_base, from_sub) + end + def test_callee assert_equal(:test_callee, __method__) assert_equal(:m, Class.new {def m; __method__; end}.new.m) |
