Bug #18624
closed`const_source_location` returns [false, 0] when autoload is defined for the constant
Description
const_source_location
returns [false, 0]
unexpectedly with the following code.
# test.rb
path = File.join(__dir__, 'test2')
Object.autoload 'Test2', path
require path
p Object.const_source_location 'Test2'
# test2.rb
class Test2
end
$ ruby -v test.rb
ruby 3.2.0dev (2022-03-11T08:38:13Z master 2e4516be26) [x86_64-linux]
[false, 0]
I expect it returns ['/path/to/test2.rb', 2]
, but it doesn't.
Ruby 2.7 ~ 3.1 have the same behavior.
I actually encountered this problem in a Rails app with Zeitwerk. The following codes are a reproducing example with Zeitwerk.
loader.setup
calls autoload
, so it causes the same problem.
# test.rb
require "zeitwerk"
loader = Zeitwerk::Loader.for_gem
loader.setup
require File.join(__dir__, 'test2')
p Zeitwerk::VERSION
p Object.const_source_location 'Test2'
# test2.rb
class Test2
end
Updated by pocke (Masataka Kuwabara) over 2 years ago
- Description updated (diff)
Updated by jeremyevans0 (Jeremy Evans) over 2 years ago
I've submitted a pull request to fix this: https://github.com/ruby/ruby/pull/5646
Updated by ufuk (Ufuk Kayserilioglu) over 2 years ago
This is a duplicate of Issue #17354 and @jeremyevans0 (Jeremy Evans), in that issue, you had argued that just because the autoload location was known didn't mean that the constant would be guaranteed to be defined by that file.
I believe this was also discussed in the Dev Meeting at the time and a consensus wasn't reached: https://bugs.ruby-lang.org/issues/17354#note-12
I suggest we close this issue and continue the conversation on #17354
Updated by jeremyevans0 (Jeremy Evans) over 2 years ago
ufuk (Ufuk Kayserilioglu) wrote in #note-3:
This is a duplicate of Issue #17354 and @jeremyevans0 (Jeremy Evans), in that issue, you had argued that just because the autoload location was known didn't mean that the constant would be guaranteed to be defined by that file.
I believe this was also discussed in the Dev Meeting at the time and a consensus wasn't reached: https://bugs.ruby-lang.org/issues/17354#note-12
I suggest we close this issue and continue the conversation on #17354
Sorry, but you are incorrect. #17354 is regarding behavior of const_source_location
before the autoloaded file is required. This issue is regarding behavior of const_source_location
after the autoloaded file is required. They are separate issues, not duplicates, and should be treated as such. This issue is definitely a bug, because the related constant has already been defined and the source of the constant is now known.
Updated by ufuk (Ufuk Kayserilioglu) over 2 years ago
jeremyevans0 (Jeremy Evans) wrote in #note-4:
Sorry, but you are incorrect. #17354 is regarding behavior of
const_source_location
before the autoloaded file is required. This issue is regarding behavior ofconst_source_location
after the autoloaded file is required. They are separate issues, not duplicates, and should be treated as such. This issue is definitely a bug, because the related constant has already been defined and the source of the constant is now known.
Indeed, thanks for the correction. I had missed the require path
line in the original reproduction example. Apologies for the noise and thanks again for the clarification.
Updated by jeremyevans (Jeremy Evans) over 2 years ago
- Status changed from Open to Closed
Applied in changeset git|c85d1cda86d75ee2c3f7b42f22c543409cb5a186.
Fix Module#const_source_location for autoload constants with direct requires
If an autoload exists for a constant, but the path for the autoload
was required, const_source_location would return [false, 0] instead
of the actual file and line. This fixes it by setting the appropriate
file and line in rb_const_set, and saving the file and line in
const_tbl_update before they get reset by current_autoload_data.
Fixes [Bug #18624]