(Originally reported in rails/rails#43691).
The debug console prevents Zeitwerk from autoloading constants that are children of namespaces defined in a file. This script reproduces the issue:
require'tmpdir'Dir.mktmpdirdo |dir|
Dir.chdir(dir)FileUtils.mkdir_p('lib/git/ref')File.write('lib/git/ref.rb','module Git::Ref; end')File.write('lib/git/ref/collection.rb','module Git::Ref::Collection; end')File.write('test.rb',<<~EOS) require 'zeitwerk' loader = Zeitwerk::Loader.new loader.push_dir('lib') loader.setup p Git::Ref::Collection EOSsystem'ruby test.rb'system'rdbg test.rb'endruby is able to autoload Git::Ref::Collection just fine.- If you type
continue in the debug console, test.rb is also executed correctly. - If, instead, you
next 4 and type eval Git::Ref::Collection you'll get a NameError. - Same if you use the
irb debugger command and try to evaluate Git::Ref::Collection in that session.
In case it matters, when Zeitwerk finds a file like ref.rb that defines a namespace, it sets a trace point on the :class event, because if the file had this content:
moduleGitmoduleRefCollectionendend
it should be able to autoload Git::Ref::Collection on line 3. In order to provide that feature, Zeitwerk listens to :class events, and as soon as the one for Git::Ref is triggered, Zeitwerk lists the contents of all git/ref directories in the root paths, and sets autoloads for what it finds. In this case, it would set an autoload for Collection on the module object stored in Git::Ref.
Problem with byebug was that Ruby does not support nested trace points. Are we in the same situation perhaps?
(Originally reported in rails/rails#43691).
The
debugconsole prevents Zeitwerk from autoloading constants that are children of namespaces defined in a file. This script reproduces the issue:rubyis able to autoloadGit::Ref::Collectionjust fine.continuein thedebugconsole,test.rbis also executed correctly.next 4and typeeval Git::Ref::Collectionyou'll get aNameError.irbdebugger command and try to evaluateGit::Ref::Collectionin that session.In case it matters, when Zeitwerk finds a file like
ref.rbthat defines a namespace, it sets a trace point on the:classevent, because if the file had this content:it should be able to autoload
Git::Ref::Collectionon line 3. In order to provide that feature, Zeitwerk listens to:classevents, and as soon as the one forGit::Refis triggered, Zeitwerk lists the contents of allgit/refdirectories in the root paths, and sets autoloads for what it finds. In this case, it would set an autoload forCollectionon the module object stored inGit::Ref.Problem with
byebugwas that Ruby does not support nested trace points. Are we in the same situation perhaps?