[ruby-core:124461] [Ruby Bug#21830] Ruby::Box and Kernel#require
Issue #21830 has been reported by fxn (Xavier Noria). ---------------------------------------- Bug #21830: Ruby::Box and Kernel#require https://bugs.ruby-lang.org/issues/21830 * Author: fxn (Xavier Noria) * Status: Open * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: UNKNOWN ---------------------------------------- If you enable `Ruby::Box`, decorations to `Kernel#require` do not work. For example, given `foo.rb`: ```ruby # foo.rb % cat foo.rb module M def require(_path) puts "decorated" super end end Kernel.prepend(M) require 'tsort' ``` the decoration works normally: ``` % ruby -v foo.rb ruby 4.0.0 (2025-12-25 revision 553f1675f3) +YJIT +PRISM [arm64-darwin25] decorated ``` and the same code does not work 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. ``` With this, Zeitwerk cannot work because it totally depends on `Kernel#require` decoration (done [here](https://github.com/fxn/zeitwerk/blob/main/lib/zeitwerk/core_ext/kernel.rb)). Bootsnap also depends on the ability of decorating `Kernel#require` (done [here](https://github.com/rails/bootsnap/blob/main/lib/bootsnap/load_path_cache/cor...)). 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 what should be the way to go in your opinion? /cc @byroot -- https://bugs.ruby-lang.org/
Issue #21830 has been updated by fxn (Xavier Noria). If you enable Ruby::Box, decorations to `Kernel#require` do not work. For example, given _foo.rb_: ```ruby 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 the same code does not work 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](https://github.com/fxn/zeitwerk/blob/main/lib/zeitwerk/core_ext/kernel.rb)). Bootsnap also depends on the ability of decorating `Kernel#require` (done [here](https://github.com/rails/bootsnap/blob/main/lib/bootsnap/load_path_cache/cor...)). 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) what should be the way to go in your opinion? /cc @byroot (Jean Boussier) ---------------------------------------- Bug #21830: Ruby::Box and Kernel#require https://bugs.ruby-lang.org/issues/21830#change-116012 * Author: fxn (Xavier Noria) * Status: Open * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: UNKNOWN ---------------------------------------- If you enable `Ruby::Box`, decorations to `Kernel#require` do not work. For example, given `foo.rb`: ```ruby # foo.rb % cat foo.rb module M def require(_path) puts "decorated" super end end Kernel.prepend(M) require 'tsort' ``` the decoration works normally: ``` % ruby -v foo.rb ruby 4.0.0 (2025-12-25 revision 553f1675f3) +YJIT +PRISM [arm64-darwin25] decorated ``` and the same code does not work 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. ``` With this, Zeitwerk cannot work because it totally depends on `Kernel#require` decoration (done [here](https://github.com/fxn/zeitwerk/blob/main/lib/zeitwerk/core_ext/kernel.rb)). Bootsnap also depends on the ability of decorating `Kernel#require` (done [here](https://github.com/rails/bootsnap/blob/main/lib/bootsnap/load_path_cache/cor...)). 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 what should be the way to go in your opinion? /cc @byroot -- https://bugs.ruby-lang.org/
Issue #21830 has been updated by fxn (Xavier Noria). Let me add that is also assumed that `Module#autoload` invokes `Kernel#require` as introduced in [cd465d5](https://github.com/ruby/ruby/commit/cd465d552c3a00341f4cb7f1d7a793d0ebcb6cde) Zeitwerk relies on this too, because the main intercepted `require` calls are coming from autoloads set by autoloaders. ---------------------------------------- Bug #21830: Ruby::Box and Kernel#require https://bugs.ruby-lang.org/issues/21830#change-116014 * Author: fxn (Xavier Noria) * Status: Open * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: UNKNOWN ---------------------------------------- If you enable `Ruby::Box`, decorations to `Kernel#require` do not work. For example, given _foo.rb_: ```ruby 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](https://github.com/fxn/zeitwerk/blob/main/lib/zeitwerk/core_ext/kernel.rb)). Bootsnap also depends on the ability of decorating `Kernel#require` (done [here](https://github.com/rails/bootsnap/blob/main/lib/bootsnap/load_path_cache/cor...)). 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) what should be the way to go in your opinion? /cc @byroot (Jean Boussier) -- https://bugs.ruby-lang.org/
Issue #21830 has been updated by tagomoris (Satoshi Tagomori). Assignee set to tagomoris (Satoshi Tagomori) ---------------------------------------- Bug #21830: Ruby::Box and Kernel#require https://bugs.ruby-lang.org/issues/21830#change-116024 * Author: fxn (Xavier Noria) * Status: Open * Assignee: tagomoris (Satoshi Tagomori) * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: UNKNOWN ---------------------------------------- If you enable `Ruby::Box`, decorations to `Kernel#require` do not work. For example, given _foo.rb_: ```ruby 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](https://github.com/fxn/zeitwerk/blob/main/lib/zeitwerk/core_ext/kernel.rb)). Bootsnap also depends on the ability of decorating `Kernel#require` (done [here](https://github.com/rails/bootsnap/blob/main/lib/bootsnap/load_path_cache/cor...)). 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) what should be the way to go in your opinion? /cc @byroot (Jean Boussier) -- https://bugs.ruby-lang.org/
Issue #21830 has been updated by tagomoris (Satoshi Tagomori). I'll work on #21881 to solve this problem. ---------------------------------------- Bug #21830: Ruby::Box and Kernel#require https://bugs.ruby-lang.org/issues/21830#change-116447 * Author: fxn (Xavier Noria) * Status: Open * Assignee: tagomoris (Satoshi Tagomori) * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: UNKNOWN ---------------------------------------- If you enable `Ruby::Box`, decorations to `Kernel#require` do not work. For example, given _foo.rb_: ```ruby 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](https://github.com/fxn/zeitwerk/blob/main/lib/zeitwerk/core_ext/kernel.rb)). Bootsnap also depends on the ability of decorating `Kernel#require` (done [here](https://github.com/rails/bootsnap/blob/main/lib/bootsnap/load_path_cache/cor...)). 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) what should be the way to go in your opinion? /cc @byroot (Jean Boussier) -- https://bugs.ruby-lang.org/
Issue #21830 has been updated by fxn (Xavier Noria). Thanks @hsbt. For the archives, I'd like to add something to
This breaks Zeitwerk's implicit namespaces
The main idea in Zeitwerk is: 1. Scan the filesystem 2. Set autoloads accordingly 3. React to constants being autoloded The `Kernel#require` decoration takes care of (3). In that decoration, we update internal state, we trigger user on load callbacks, etc. So, while it is correct that implicit namespaces won't work, the implications are more dramatic: Zeitwerk in general won't work, callbacks won't fire, reloading won't know what to reload, etc. If the decoration is not in place the gem is generally broken. ---------------------------------------- Bug #21830: Ruby::Box and Kernel#require https://bugs.ruby-lang.org/issues/21830#change-118680 * Author: fxn (Xavier Noria) * Status: Open * Assignee: tagomoris (Satoshi Tagomori) * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: UNKNOWN ---------------------------------------- If you enable `Ruby::Box`, decorations to `Kernel#require` do not work. For example, given _foo.rb_: ```ruby 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](https://github.com/fxn/zeitwerk/blob/main/lib/zeitwerk/core_ext/kernel.rb)). Bootsnap also depends on the ability of decorating `Kernel#require` (done [here](https://github.com/rails/bootsnap/blob/main/lib/bootsnap/load_path_cache/cor...)). 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) what should be the way to go in your opinion? /cc @byroot (Jean Boussier) -- https://bugs.ruby-lang.org/
Issue #21830 has been updated by hsbt (Hiroshi SHIBATA). Status changed from Open to Closed @fxn Thank you for your following up. I merged https://github.com/ruby/ruby/pull/18534, so `rails s` is now working with `RUBY_BOX=1`. I'm traking the support status of RubyGems and Ruby::Box at https://bugs.ruby-lang.org/issues/22275 ---------------------------------------- Bug #21830: Ruby::Box and Kernel#require https://bugs.ruby-lang.org/issues/21830#change-118734 * Author: fxn (Xavier Noria) * Status: Closed * Assignee: tagomoris (Satoshi Tagomori) * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: UNKNOWN ---------------------------------------- If you enable `Ruby::Box`, decorations to `Kernel#require` do not work. For example, given _foo.rb_: ```ruby 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](https://github.com/fxn/zeitwerk/blob/main/lib/zeitwerk/core_ext/kernel.rb)). Bootsnap also depends on the ability of decorating `Kernel#require` (done [here](https://github.com/rails/bootsnap/blob/main/lib/bootsnap/load_path_cache/cor...)). 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) what should be the way to go in your opinion? /cc @byroot (Jean Boussier) -- https://bugs.ruby-lang.org/
participants (3)
-
fxn (Xavier Noria) -
hsbt (Hiroshi SHIBATA) -
tagomoris (Satoshi Tagomori)