[ruby-core:121623] [Ruby Misc#21154] Document or change Module#autoload?
From:
"mame (Yusuke Endoh) via ruby-core" <ruby-core@...>
Date:
2025-04-10 15:26:55 UTC
List:
ruby-core #121623
Issue #21154 has been updated by mame (Yusuke Endoh).
@fxn Sorry for the delay. I finally watched your video.
I'm not exactly sure what you meant by "const_get hook", but perhaps you meant "const_added"? I'll assume that's the case and continue.
Here's how I understand the issue.
Suppose we have a gem with lib/foo.rb and lib/foo/bar.rb, and an app.rb that requires it:
```ruby
# lib/foo.rb
Zeitwerk::Loader.for_gem.setup
module Foo
end
```
```ruby
# lib/foo/bar.rb
module Foo
class Bar
end
end
```
```ruby
# app.rb
require "foo"
Foo::Bar
```
In this setup, `Zeitwerk::Loader.for_gem.setup` in lib/foo.rb effectively does something like this:
```ruby
# Since lib/foo.rb exists, it sets autoload for ::Foo
autoload :Foo, "lib/foo"
# Then, using the const_added hook, it sets autoload for Foo::Bar when Foo is defined:
class Object
def self.const_added(name)
if name == :Foo
Foo.autoload(:Bar, "lib/foo/bar")
end
end
end
```
This means that lib/foo.rb sets `autoload :Foo, "lib/foo"`, which would violate the rule of my documentation patch.
Is this understanding correct?
---
If that's the case, I think lib/foo.rb is doing something quite tricky. Let me show a simpler example:
```ruby
# test.rb
p 1
autoload :Foo, "./test"
p 2
class Foo
p 3
end
```
Running this code produces the following output:
```
$ ruby test.rb
1
2
1
2
3
3
```
This shows that `class Foo` triggers the autoload and ends up circularly loading test.rb itself. As a result, the file ends up being evaluated twice.
Is this kind of circular loading what actually happens in `Zeitwerk::Loader.for_gem.setup`? If so, is this really the intended behavior?
---
By the way, I appreciate your kindness in recording a video, but to be honest, I'm not very good at understanding spoken English. I'd appreciate it if you could explain things in text and using code examples.
Also, this month's dev meeting will be held at RubyKaigi, a Japanese conference, and will be shorter than usual, so I don't think we'll have time to discuss this topic. I'm sorry, but I think we'll need to revisit it in the May dev meeting.
----------------------------------------
Misc #21154: Document or change Module#autoload?
https://bugs.ruby-lang.org/issues/21154#change-112678
* Author: fxn (Xavier Noria)
* Status: Feedback
* Assignee: mame (Yusuke Endoh)
----------------------------------------
The documentation of `Module#autoload?` says
> Returns filename to be loaded if name is registered as autoload in the namespace of mod or one of its ancestors.
Cool, but in the following snippet
```ruby
autoload :Foo, 'foo'
autoload?(:Foo)
```
the second line could evaluate to `nil`, and this does not seem to agree. I just registered an autoload, therefore (according to the documentation) I should get "foo" back in line 2.
I'd like to ask for clarification from the Ruby team:
1. Is the documentation complete? Should that second line always return "foo"?
2. If the answer is no, which is the logic missing in the docs?
Thank you!
--
https://bugs.ruby-lang.org/
______________________________________________
ruby-core mailing list -- ruby-core@ml.ruby-lang.org
To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/