Issue #17379 has been updated by shugo (Shugo Maeda).

Assignee changed from shugo (Shugo Maeda) to ko1 (Koichi Sasada)

It seems that callable method entry cache caused the problem.
The problem doesn't occur with the following patch:

```
diff --git a/vm_method.c b/vm_method.c
index a0ccdb8a51..d3a3926780 100644
--- a/vm_method.c
+++ b/vm_method.c
@@ -1023,7 +1023,7 @@ prepare_callable_method_entry(VALUE defined_class, ID id, const rb_method_entry_
                     mtbl = RCLASS_EXT(defined_class)->callable_m_tbl = rb_id_table_create(0);
                 }
                 cme = rb_method_entry_complement_defined_class(me, me->called_id, defined_class);
-                rb_id_table_insert(mtbl, id, (VALUE)cme);
+                // rb_id_table_insert(mtbl, id, (VALUE)cme);
                 RB_OBJ_WRITTEN(defined_class, Qundef, (VALUE)cme);
                 VM_ASSERT(callable_method_entry_p(cme));
             }
@@ -1122,7 +1122,8 @@ callable_method_entry(VALUE klass, ID mid, VALUE *defined_class_ptr)
     VM_ASSERT(RB_TYPE_P(klass, T_CLASS) || RB_TYPE_P(klass, T_ICLASS));
     RB_VM_LOCK_ENTER();
     {
-        cme = cached_callable_method_entry(klass, mid);
+        // cme = cached_callable_method_entry(klass, mid);
+        cme = NULL;
 
         if (cme) {
             if (defined_class_ptr != NULL) *defined_class_ptr = cme->defined_class;
@@ -1139,7 +1140,7 @@ callable_method_entry(VALUE klass, ID mid, VALUE *defined_class_ptr)
                 cme = negative_cme(mid);
             }
 
-            cache_callable_method_entry(klass, mid, cme);
+            // cache_callable_method_entry(klass, mid, cme);
         }
     }
     RB_VM_LOCK_LEAVE();
```

(The fix of prepare_callable_method_entry() is for Kernel#method)

@ko1, is there any way to fix the problem without performance regression?



----------------------------------------
Bug #17379: Refinement with modules redefinition bug
https://bugs.ruby-lang.org/issues/17379#change-89429

* Author: marcandre (Marc-Andre Lafortune)
* Status: Open
* Priority: Normal
* Assignee: ko1 (Koichi Sasada)
* ruby -v: ruby 3.0.0dev (2020-12-05T10:40:00Z master 9dbb2bfd73) [x86_64-darwin18]
* Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN
----------------------------------------
Depending on the circumstance, a refinement can be modified even after being used:

```ruby
def foo
  [:base]
end

module M
  def foo
    super << :M
  end
end

module Ext
  refine Object do
    include M
  end
end

using Ext

p 'asd'.foo unless ENV['SKIP'] # => [:base, :M] (ok)

module M
  def foo
    super << :new_ref
  end
end

p 'asd'.foo # => depends (not ok)
```

Running this gives:
```
$ ruby refinement.rb
[:base, :M]
[:base, :M] # => ok
$ SKIP=t ruby refinement.rb
[:base, :new_ref]  # => should be [:base, :M]
```



-- 
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>