ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
From: merch-redmine@jeremyevans.net
To: ruby-core@ruby-lang.org
Subject: [ruby-core:102889] [Ruby master Bug#17519] set_visibility fails when a prepended module and a refinement both exist
Date: Tue, 16 Mar 2021 19:25:05 +0000 (UTC)	[thread overview]
Message-ID: <redmine.journal-90950.20210316192503.48474@ruby-lang.org> (raw)
In-Reply-To: redmine.issue-17519.20210108191508.48474@ruby-lang.org

Issue #17519 has been updated by jeremyevans0 (Jeremy Evans).

Backport changed from 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN to 2.5: UNKNOWN, 2.6: REQUIRED, 2.7: REQUIRED, 3.0: REQUIRED

fledman (David Feldman) wrote in #note-6:
> do you plan to backport the fix to any of the supported 2.x versions?

The choice of which patches to backport is up to the branch maintainer. I've marked this for backporting, but it is their decision.

----------------------------------------
Bug #17519: set_visibility fails when a prepended module and a refinement both exist
https://bugs.ruby-lang.org/issues/17519#change-90950

* 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: REQUIRED, 3.0: REQUIRED
----------------------------------------
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/

  parent reply	other threads:[~2021-03-16 19:25 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 ` merch-redmine [this message]
2021-03-20  7:30 ` [ruby-core:102956] " nagachika00
2021-04-02  7:01 ` [ruby-core:103169] " naruse
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-90950.20210316192503.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).