Bug #21830
openRuby::Box and Kernel#require
Description
If you enable Ruby::Box, decorations to Kernel#require do not work.
For example, given foo.rb:
module M
def require(_path)
puts 'decorated'
super
end
end
Kernel.prepend(M)
p require 'tsort'
the decoration works normally:
% ruby -v foo.rb
ruby 4.0.0 (2025-12-25 revision 553f1675f3) +YJIT +PRISM [arm64-darwin25]
decorated
true
but it does not with the feature enabled:
% RUBY_BOX=1 ruby -v foo.rb
ruby 4.0.0 (2025-12-25 revision 553f1675f3) +YJIT +PRISM [arm64-darwin25]
ruby: warning: Ruby::Box is experimental, and the behavior may change in the future!
See https://docs.ruby-lang.org/en/4.0/Ruby/Box.html for known issues, etc.
true
With this, Zeitwerk cannot work because it totally depends on a decoration of Kernel#require (done here).
Bootsnap also depends on the ability of decorating Kernel#require (done here).
On one hand, these gems are walking a fine line in the border of the public interface of Ruby. On the other hand, it is a goal of boxes to be transparent to the code being loaded under them.
@tagomoris (Satoshi Tagomori) (Satoshi Tagomori) what should be the way to go in your opinion?
/cc @byroot (Jean Boussier) (Jean Boussier)
Updated by fxn (Xavier Noria) 29 days ago
- Description updated (diff)
Updated by fxn (Xavier Noria) 28 days ago
ยท Edited
Just in case it matters, let me also add that it is assumed that Module#autoload invokes Kernel#require as introduced in cd465d5.
Zeitwerk relies on this too, because the main intercepted require calls are coming from autoloads set by autoloaders.
Updated by tagomoris (Satoshi Tagomori) 27 days ago
- Assignee set to tagomoris (Satoshi Tagomori)