From: naruse@airemix.jp
To: ruby-core@ruby-lang.org
Subject: [ruby-core:103169] [Ruby master Bug#17519] set_visibility fails when a prepended module and a refinement both exist
Date: Fri, 02 Apr 2021 07:01:30 +0000 (UTC) [thread overview]
Message-ID: <redmine.journal-91242.20210402070130.48474@ruby-lang.org> (raw)
In-Reply-To: redmine.issue-17519.20210108191508.48474@ruby-lang.org
Issue #17519 has been updated by naruse (Yui NARUSE).
Backport changed from 2.5: UNKNOWN, 2.6: REQUIRED, 2.7: DONE, 3.0: REQUIRED to 2.5: UNKNOWN, 2.6: REQUIRED, 2.7: DONE, 3.0: DONE
ruby_3_0 d1cec0bca588266b9af1d55e592016c45ee68fbb merged revision(s) 58660e943488778563b9e41005a601e9660ce21f.
----------------------------------------
Bug #17519: set_visibility fails when a prepended module and a refinement both exist
https://bugs.ruby-lang.org/issues/17519#change-91242
* Author: fledman (David Feldman)
* Status: Closed
* Priority: Normal
* ruby -v: ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-darwin19]
* Backport: 2.5: UNKNOWN, 2.6: REQUIRED, 2.7: DONE, 3.0: DONE
----------------------------------------
the set_visibility functions (aka public/private/protected) fail with NameError when:
* called on a specific object's singleton class
* for a specific method
* and both of the following are true
* any module has been prepended to the object's class
* a refinement exists for the specific method
note that the refinement does not need to ever be used
I have reproduced this on 3.0.0, 2.7.2, and 2.6.6 (those were the only 3 version I tested)
``` ruby
def test_visibility(function)
h1 = {x:1, y:1}
h2 = {x:2, y:2}
h1.singleton_class.send(:private, function)
h2.singleton_class.send(:public, function)
begin
puts h1.public_send(function, :x)
rescue NoMethodError => err
puts "hit NoMethodError as expected: #{err.inspect}"
end
puts h2.public_send(function, :x)
end
```
succeeds without any prepended modules or refinements:
```ruby
irb> test_visibility :except
hit NoMethodError as expected: #<NoMethodError: private method `except' called for {:x=>1, :y=>1}:Hash>
{:y=>2}
=> nil
```
succeeds with only a prepended module:
```ruby
irb> module Nothing; end; Hash.prepend(Nothing); Hash.ancestors
=> [Nothing, Hash, Enumerable, Object, PP::ObjectMixin, Kernel, BasicObject]
irb> test_visibility :except
hit NoMethodError as expected: #<NoMethodError: private method `except' called for {:x=>1, :y=>1}:Hash>
{:y=>2}
=> nil
```
succeeds with only a refinement:
```ruby
irb> module NeverUsed
refine Hash do
def except(*keys)
{never: 'used'}
end
end
end
=> #<refinement:Hash@NeverUsed>
irb> test_visibility :except
hit NoMethodError as expected: #<NoMethodError: private method `except' called for {:x=>1, :y=>1}:Hash>
{:y=>2}
=> nil
```
fails with both a refinement and a prepended module:
```ruby
irb> module Nothing; end; Hash.prepend(Nothing); Hash.ancestors
=> [Nothing, Hash, Enumerable, Object, PP::ObjectMixin, Kernel, BasicObject]
irb> module NeverUsed
refine Hash do
def except(*keys)
{never: 'used'}
end
end
end
=> #<refinement:Hash@NeverUsed>
irb> test_visibility :except
Traceback (most recent call last):
6: from .rubies/ruby-3.0.0/bin/irb:23:in `<main>'
5: from .rubies/ruby-3.0.0/bin/irb:23:in `load'
4: from .rubies/ruby-3.0.0/lib/ruby/gems/3.0.0/gems/irb-1.3.0/exe/irb:11:in `<top (required)>'
3: from (irb):25:in `<main>'
2: from (irb):5:in `test_visibility'
1: from (irb):5:in `private'
NameError (undefined method `except' for class `#<Class:#<Hash:0x00007ffd6b176f18>>')
Did you mean? exec
# non-refined method still works
irb> test_visibility :fetch
hit NoMethodError as expected: #<NoMethodError: private method `fetch' called for {:x=>1, :y=>1}:Hash>
2
=> nil
```
--
https://bugs.ruby-lang.org/
next prev parent reply other threads:[~2021-04-02 7:01 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-01-08 19:15 [ruby-core:101981] [Ruby master Bug#17519] set_visibility fails when a prepended module and a refinement both exist dbfeldman
2021-01-08 19:29 ` [ruby-core:101982] " dbfeldman
2021-01-08 19:45 ` [ruby-core:101983] " dbfeldman
2021-01-11 19:01 ` [ruby-core:102004] " dbfeldman
2021-03-16 19:12 ` [ruby-core:102888] " dbfeldman
2021-03-16 19:25 ` [ruby-core:102889] " merch-redmine
2021-03-20 7:30 ` [ruby-core:102956] " nagachika00
2021-04-02 7:01 ` naruse [this message]
2021-04-05 21:52 ` [ruby-core:103244] " dbfeldman
2021-04-05 23:06 ` [ruby-core:103245] " merch-redmine
2021-04-24 9:57 ` [ruby-core:103583] " nagachika00
2021-05-29 5:56 ` [ruby-core:104095] " nagachika00
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.ruby-lang.org/en/community/mailing-lists/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=redmine.journal-91242.20210402070130.48474@ruby-lang.org \
--to=ruby-core@ruby-lang.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).