From: "Eregon (Benoit Daloze)" Date: 2022-08-20T12:30:53+00:00 Subject: [ruby-core:109593] [Ruby master Bug#18435] Calling `protected` on ancestor method changes result of `instance_methods(false)` Issue #18435 has been updated by Eregon (Benoit Daloze). @nagachika wrote in #note-14: > I agree to backport the revert to ruby_3_1, but I think removing the existing methods in stable releases could be a severe damage to the depending applications/libraries. > I'd like to add dummy methods {Method,UnboundMethod}#{public?,protected?,private?} with warnings in 3.1.3. > @matz @jeremyevans0 I propose to the dummy implementation of {Method,UnboundMethod}#public? return true constantly, and the others return false. Do you have any objection for adding dummy methods? Since https://github.com/ruby/ruby/pull/6242 these methods are no longer problematic (Method == method entry). Also see https://bugs.ruby-lang.org/issues/11689#note-27 I am not sure what to backport if anything. Possibilities I see: * Keep the methods for 3.1.x and accept they are confusing for zsuper methods in 3.1 (fixed in 3.2). Would be good to document that in the methods' rdoc and possibly release notes. Maybe even emit some warning as Jeremy suggests. * Backport https://github.com/ruby/ruby/pull/6242, since it does fix bugs #18435 #18729 (#18751 too but I that seems master-only). Unsure if it's a good idea to backport since it's a bigger change (and every bug fix is a potential incompatibility). * Remove the {public?,protected?,private?} methods. I think this makes sense because we want people to not use them in 3.1 as they are kind of broken, and code which feature checks correctly with `method.respond_to?(:public)` will then work correctly no matter <3.1, 3.1 or 3.2 (assuming the code uses a fallback). ---------------------------------------- Bug #18435: Calling `protected` on ancestor method changes result of `instance_methods(false)` https://bugs.ruby-lang.org/issues/18435#change-98775 * Author: ufuk (Ufuk Kayserilioglu) * Status: Closed * Priority: Normal * Assignee: Eregon (Benoit Daloze) * ruby -v: ruby 2.7.5p203 (2021-11-24 revision f69aeb8314) [x86_64-darwin20] * Backport: 2.6: DONTNEED, 2.7: DONTNEED, 3.0: DONTNEED, 3.1: REQUIRED ---------------------------------------- As documented `instance_methods(false)` works as follows: ```ruby module A def method1() end end class B include A def method2() end end p B.instance_methods(false) #=> [:method2] ``` However, calling `protected` on the method defined by `A`, unexpectedly changes the result of `instance_methods(false)` on `B`, even though the owner of the method is still `A`: ```ruby module A def method1() end end class B include A protected :method1 def method2() end end p B.instance_methods(false) #=> [:method1, :method2] p B.instance_method(:method1).owner #=> A ``` In contrast, calling `private` or `public` on the same method does not cause any changes on the result of `B.instance_methods(false)`. This feels like a bug in the implementation of `instance_methods(false)`, but, if it is by design, it should at least be documented on `Module#instance_methods`. This reproduction script gives the same output all the way from Ruby 2.0 up to Ruby-HEAD: https://wandbox.org/permlink/LqbXMBTYxURRZmDz -- https://bugs.ruby-lang.org/ Unsubscribe: