[#104004] [Ruby master Feature#17883] Load bundler/setup earlier to make `bundle exec ruby -r` respect Gemfile — mame@...
Issue #17883 has been reported by mame (Yusuke Endoh).
21 messages
2021/05/24
[ruby-core:103906] [Ruby master Bug#17822] Inconsistent visibility behavior with refinements
From:
ko1@...
Date:
2021-05-20 07:05:24 UTC
List:
ruby-core #103906
Issue #17822 has been updated by ko1 (Koichi Sasada).
Thank you the patch. It seems good. Could you commit with a test?
----------------------------------------
Bug #17822: Inconsistent visibility behavior with refinements
https://bugs.ruby-lang.org/issues/17822#change-92034
* Author: alanwu (Alan Wu)
* Status: Open
* Priority: Normal
* Backport: 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN
----------------------------------------
Running the following script, case 0 raises `NoMethodError` for privacy violation,
while all other cases print `:refined`. Shouldn't all three cases be equivalent?
```ruby
class A; end
module M
refine(A) { def foo; :refined; end }
end
case ARGV.first.to_i
when 0
class A
private def foo; end
end
when 1
class A
prepend(Module.new)
private def foo; end
end
when 2
class A
private
def foo; end
end
end
using(M)
p(A.new.foo)
```
---
Some analysis: case 0 on master(cb78aae) behaves differently from version 3.0.1.
Applying the patch from https://github.com/ruby/ruby/pull/4357 recovers the behavior
found on `3.0.1`. That patch plus the following diff makes case 0 behave like case 1 and 2.
```diff
diff --git a/vm_method.c b/vm_method.c
index 0f25c514a8..82ac3a60b3 100644
--- a/vm_method.c
+++ b/vm_method.c
@@ -1399,11 +1399,16 @@ rb_export_method(VALUE klass, ID name, rb_method_visibility_t visi)
rb_vm_check_redefinition_opt_method(me, klass);
if (klass == defined_class || origin_class == defined_class) {
- METHOD_ENTRY_VISI_SET(me, visi);
-
- if (me->def->type == VM_METHOD_TYPE_REFINED && me->def->body.refined.orig_me) {
- METHOD_ENTRY_VISI_SET((rb_method_entry_t *)me->def->body.refined.orig_me, visi);
- }
+ if (me->def->type == VM_METHOD_TYPE_REFINED) {
+ // Refinement method entries should always be public because the refinement
+ // search is always performed.
+ if (me->def->body.refined.orig_me) {
+ METHOD_ENTRY_VISI_SET((rb_method_entry_t *)me->def->body.refined.orig_me, visi);
+ }
+ }
+ else {
+ METHOD_ENTRY_VISI_SET(me, visi);
+ }
rb_clear_method_cache(klass, name);
}
else {
```
--
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>