From: "jeremyevans0 (Jeremy Evans)" Date: 2022-04-15T14:51:07+00:00 Subject: [ruby-core:108265] [Ruby master Bug#18729] Method#owner and UnboundMethod#owner are incorrect after using Module#public/protected/private Issue #18729 has been updated by jeremyevans0 (Jeremy Evans). Eregon (Benoit Daloze) wrote in #note-3: > > I'm not sure if this is a bug, since the current behavior seems intentional. > > Why do you think it might be intentional? > It sounds like a clear implementation bug to me (which I guess wasn't found until now, or maybe not deemed worth fixing if found by others). The code deliberates handles ZSUPER methods by looking for the method entry that actually handles the method, instead of using the ZSUPER method entry. There is no way this is an accidental bug, it's a deliberate implementation choice. Note that my pull request doesn't change the underlying implementation, it still uses the method entry that actually handles the method. My pull request only records the necessary metadata so that `owner`/`inspect`/`super_method` return results as if the ZSUPER method entry was used. ---------------------------------------- Bug #18729: Method#owner and UnboundMethod#owner are incorrect after using Module#public/protected/private https://bugs.ruby-lang.org/issues/18729#change-97287 * Author: Eregon (Benoit Daloze) * Status: Open * Priority: Normal * ruby -v: ruby 3.1.1p18 (2022-02-18 revision 53f5fc4236) [x86_64-linux] * Backport: 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN ---------------------------------------- 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: ```ruby 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: ``` [#, A, [], [:foo]] [#, 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: ``` [#, A, [], [:foo]] [#, B, [:foo], [:foo]] ``` -- https://bugs.ruby-lang.org/ Unsubscribe: