Project

General

Profile

Actions

Bug #18729

closed

Method#owner and UnboundMethod#owner are incorrect after using Module#public/protected/private

Added by Eregon (Benoit Daloze) 2 months ago. Updated 10 days ago.

Status:
Rejected
Priority:
Normal
Assignee:
-
Target version:
-
ruby -v:
ruby 3.1.1p18 (2022-02-18 revision 53f5fc4236) [x86_64-linux]
[ruby-core:108235]

Description

The #owner should be "the class or module that defines the method".
Or in other words, the owner is the module which has the method table containing that method.

This generally holds, and it seems very likely this assumption is relied upon (e.g., when decorating a method, undefining it, etc).
But the returned value on CRuby is incorrect for this case:

class A
  protected def foo
    :A
  end
end

class B < A
  p [instance_method(:foo), instance_method(:foo).owner, instance_methods(false), A.instance_methods(false)]
  public :foo
  p [instance_method(:foo), instance_method(:foo).owner, instance_methods(false), A.instance_methods(false)]
end

It gives:

[#<UnboundMethod: B(A)#foo() owner.rb:2>, A, [], [:foo]]
[#<UnboundMethod: B(A)#foo() owner.rb:2>, A, [:foo], [:foo]]

So UnboundMethod#owner says A, but clearly there is a :foo method entry in B created by public :foo, and that is shown through B.instance_methods(false).

The expected output is:

[#<UnboundMethod: B(A)#foo() owner.rb:2>, A, [], [:foo]]
[#<UnboundMethod: B#foo() owner.rb:2>, B, [:foo], [:foo]]

Related issues 2 (2 open0 closed)

Related to Ruby master - Bug #18751: Regression on master for Method#== when comparing public with private methodOpenActions
Related to Ruby master - Bug #18435: Calling `protected` on ancestor method changes result of `instance_methods(false)`OpenActions
Actions

Also available in: Atom PDF