[ruby-core:117445] [Ruby master Bug#20411] Kenrel.autoload? behaviour

Issue #20411 has been reported by gmcgibbon (Gannon McGibbon). ---------------------------------------- Bug #20411: Kenrel.autoload? behaviour https://bugs.ruby-lang.org/issues/20411 * Author: gmcgibbon (Gannon McGibbon) * Status: Open * ruby -v: 3.3.0 * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- 👋 I recently tried checking if a top-level constant was autoloaded within a module, and it doesn't seem to work properly when calling `autoload?` from `Kernel`. Here's a simple reproduction script: ``` autoload :A, "a.rb" module B puts Kernel.autoload?(:A) # nil puts Module.autoload?(:A) # a.rb end puts Kernel.autoload?(:A) # a.rb puts Module.autoload?(:A) # a.rb ``` I would expect `Kernel.autoload?` and `Module.autoload?` to behave the same way, and return the path of the autoloaded constant until it is loaded. -- https://bugs.ruby-lang.org/

Issue #20411 has been updated by jeremyevans0 (Jeremy Evans). These are separate methods: Kernel.autoload?/Kernel#autoload? (it's a global/module function) is documented here: https://docs.ruby-lang.org/en/master/Kernel.html#method-i-autoload-3F Module#autoload? is documented here: https://docs.ruby-lang.org/en/master/Module.html#method-i-autoload-3F Once you understand that Kernel.autoload? and Kernel#autoload? are the same method, the behavior makes more sense: ```ruby autoload :A, "a.rb" module B puts Kernel.autoload?(:A) # nil puts Module.autoload?(:A) # a.rb puts autoload?(:A) # nil puts B.autoload?(:A) # nil end puts Kernel.autoload?(:A) # a.rb puts Module.autoload?(:A) # a.rb puts autoload?(:A) # a.rb puts B.autoload?(:A) # nil ``` `Kernel#autoload?` looks up in the currently open namespace, so `Kernel.autoload?` does as well. Not defining `Kernel.autoload?` as a singleton method would fix the behavior, but would break backwards compatibility. I don't think it is worth changing. The behavior is currently expected and not a bug. I'm leaving this open as I think the documentation for `Kernel#autoload?` should be improved to mention it uses the current namespace. ---------------------------------------- Bug #20411: Kenrel.autoload? behaviour https://bugs.ruby-lang.org/issues/20411#change-107827 * Author: gmcgibbon (Gannon McGibbon) * Status: Open * ruby -v: 3.3.0 * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- 👋 I recently tried checking if a top-level constant was autoloaded within a module, and it doesn't seem to work properly when calling `autoload?` from `Kernel`. Here's a simple reproduction script: ``` autoload :A, "a.rb" module B puts Kernel.autoload?(:A) # nil puts Module.autoload?(:A) # a.rb end puts Kernel.autoload?(:A) # a.rb puts Module.autoload?(:A) # a.rb ``` I would expect `Kernel.autoload?` and `Module.autoload?` to behave the same way, and return the path of the autoloaded constant until it is loaded. -- https://bugs.ruby-lang.org/

Issue #20411 has been updated by gmcgibbon (Gannon McGibbon). Ah, I see. Thank you for clarifying! Strangely, if you use `class B` and not a `module B`, the behaviour changes. Do classes not count as a namespace? I agree the documentation could be improved. I will submit a patch to improve the docs. ---------------------------------------- Bug #20411: Kenrel.autoload? behaviour https://bugs.ruby-lang.org/issues/20411#change-107828 * Author: gmcgibbon (Gannon McGibbon) * Status: Open * ruby -v: 3.3.0 * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- 👋 I recently tried checking if a top-level constant was autoloaded within a module, and it doesn't seem to work properly when calling `autoload?` from `Kernel`. Here's a simple reproduction script: ``` autoload :A, "a.rb" module B puts Kernel.autoload?(:A) # nil puts Module.autoload?(:A) # a.rb end puts Kernel.autoload?(:A) # a.rb puts Module.autoload?(:A) # a.rb ``` I would expect `Kernel.autoload?` and `Module.autoload?` to behave the same way, and return the path of the autoloaded constant until it is loaded. -- https://bugs.ruby-lang.org/

Issue #20411 has been updated by jeremyevans0 (Jeremy Evans). gmcgibbon (Gannon McGibbon) wrote in #note-2:
Ah, I see. Thank you for clarifying! Strangely, if you use `class B` and not a `module B`, the behaviour changes. Do classes not count as a namespace? I agree the documentation could be improved. I will submit a patch to improve the docs.
The lookup considers autoloads in ancestors, and unless you are subclassing BasicObject, your class eventually subclasses Object, which is the location for autoloads at top level. Classes have superclasses, modules do not. Modules still have ancestors (other included modules), but as Object is a class and not a module, lookup for a module will not look up into Object. ---------------------------------------- Bug #20411: Kenrel.autoload? behaviour https://bugs.ruby-lang.org/issues/20411#change-107829 * Author: gmcgibbon (Gannon McGibbon) * Status: Open * ruby -v: 3.3.0 * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- 👋 I recently tried checking if a top-level constant was autoloaded within a module, and it doesn't seem to work properly when calling `autoload?` from `Kernel`. Here's a simple reproduction script: ``` autoload :A, "a.rb" module B puts Kernel.autoload?(:A) # nil puts Module.autoload?(:A) # a.rb end puts Kernel.autoload?(:A) # a.rb puts Module.autoload?(:A) # a.rb ``` I would expect `Kernel.autoload?` and `Module.autoload?` to behave the same way, and return the path of the autoloaded constant until it is loaded. -- https://bugs.ruby-lang.org/

Issue #20411 has been updated by jeremyevans0 (Jeremy Evans). Status changed from Open to Closed Fixed by commit:1984f9aedcbb11f0770257eb5ecd4d4f37e0efd5 ---------------------------------------- Bug #20411: Kenrel.autoload? behaviour https://bugs.ruby-lang.org/issues/20411#change-107902 * Author: gmcgibbon (Gannon McGibbon) * Status: Closed * ruby -v: 3.3.0 * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- 👋 I recently tried checking if a top-level constant was autoloaded within a module, and it doesn't seem to work properly when calling `autoload?` from `Kernel`. Here's a simple reproduction script: ``` autoload :A, "a.rb" module B puts Kernel.autoload?(:A) # nil puts Module.autoload?(:A) # a.rb end puts Kernel.autoload?(:A) # a.rb puts Module.autoload?(:A) # a.rb ``` I would expect `Kernel.autoload?` and `Module.autoload?` to behave the same way, and return the path of the autoloaded constant until it is loaded. -- https://bugs.ruby-lang.org/
participants (2)
-
gmcgibbon (Gannon McGibbon)
-
jeremyevans0 (Jeremy Evans)