[ruby-core:109478] [Ruby master Bug#18435] Calling `protected` on ancestor method changes result of `instance_methods(false)`
From:
"jeremyevans0 (Jeremy Evans)" <noreply@...>
Date:
2022-08-13 03:31:32 UTC
List:
ruby-core #109478
Issue #18435 has been updated by jeremyevans0 (Jeremy Evans).
nagachika (Tomoyuki Chikanaga) 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?
I don't have a preference on whether the methods are kept or removed in 3.1. However, I think if we are going to keep the methods in 3.1, we should just have them emit a deprecation warning instead of changing their behavior.
----------------------------------------
Bug #18435: Calling `protected` on ancestor method changes result of `instance_methods(false)`
https://bugs.ruby-lang.org/issues/18435#change-98645
* Author: ufuk (Ufuk Kayserilioglu)
* Status: Closed
* Priority: Normal
* 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: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>