[ruby-core:126463] [Ruby Bug#22257] Prepending a module to an already-included module leaves stale super caches
Issue #22257 has been updated by eightbitraptor (Matt V-H). I've created Backport patches [for 4.0](https://github.com/ruby/ruby/pull/18422) and [for 3.4](https://github.com/ruby/ruby/pull/18423) ---------------------------------------- Bug #22257: Prepending a module to an already-included module leaves stale super caches https://bugs.ruby-lang.org/issues/22257#change-118614 * Author: eightbitraptor (Matt V-H) * Status: Open * Target version: 4.1 * Backport: 3.3: WONTFIX, 3.4: REQUIRED, 4.0: REQUIRED ---------------------------------------- When a module is prepended to a module that already has includers, super call sites inside the prepended module keep calling the old method entry after the method is redefined. [**Fix implemented in this PR**](https://github.com/ruby/ruby/pull/18421) <pre> module M; def foo; :m; end; end class D; include M; end M.prepend(Module.new { def foo; super; end }) D.new.foo # prime the super call-site cache M.send(:define_method, :foo) { :hooked } p D.new.foo </pre> I found this while working on an unrelated Ractor issue. But this problem manifests itself for Ractors as follows: <pre> Ractor.new {} require 'set' Kernel.send(:define_method, :require) { |f| $hook = f } require 'set' p $hook # => nil, the hook never runs </pre> This is because creating the first Ractor prepends an internal `RactorRequire` wrapper onto Kernel. After the first require primes the cache in the wrapper, redefining Kernel#require silently does nothing. The linked PR fixes this by registering the backfilled iclass in the module's subclasses list, after the includer walk finishes. -- https://bugs.ruby-lang.org/
participants (1)
-
eightbitraptor (Matt V-H)