From: "Eregon (Benoit Daloze) via ruby-core" Date: 2024-01-18T16:58:23+00:00 Subject: [ruby-core:116303] [Ruby master Bug#20188] `Module#const_source_location` returns wrong information when real constant was defined but autoload is still ongoing Issue #20188 has been updated by Eregon (Benoit Daloze). fxn (Xavier Noria) wrote in #note-5: > That output was meant to be what I'd expect from the previous example (which triggers the autoload). The whole program would be: That's how I understood it, but I somehow missed the `Bar rescue nil` when reading the code. So the current behavior seems to be that if the autoload fails then the autoload remains and keeps failing (and it even re-evaluates the file each time). The `Bar = 1` in `/tmp/bar.rb` is never published because the autoload raised, so effectively after the autoload returned by failing it is the same as if that constant was never set. And in that logic, it does make sense that `const_source_location` still points at the autoload line, because in terms of state `Bar` has never been "assigned publicly". By "assigned publicly" I mean the value is no longer private to the autoload but published to all. So with these semantics that exception in autoload does not publish the constant, the current behavior for `const_source_location` seems better. Changing it would make `const_source_location` and `autoload?` inconsistent, like: ```ruby File.write('/tmp/bar.rb', 'Bar = 1; raise') autoload :Bar, '/tmp/bar' Bar rescue nil p Object.const_source_location(:Bar) # ["/tmp/bar.rb", 1] with this change, ["foo.rb", 2] before. ["foo.rb", 2] is better because there is no constant Bar set and the assignment during the failed autoload was never published. p Object.autoload?(:Bar) # "/tmp/bar" this means the autoload is still there and will be used for the next reference to Bar (just below) p Bar # raises ``` Regarding your expected output, yeah it makes sense if the constant was published (if present) even if the autoload raised an exception. I'm not sure why autoload behaves that way on exception and does not publish (possibly this was discussed before and I forgot, it does seem better than the older behavior of special "undefined constants" on failed autoload). It does feel like something that would be worth to discuss and try to change. ---------------------------------------- Bug #20188: `Module#const_source_location` returns wrong information when real constant was defined but autoload is still ongoing https://bugs.ruby-lang.org/issues/20188#change-106325 * Author: byroot (Jean Boussier) * Status: Open * Priority: Normal * ruby -v: ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin23] * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- Ref: https://github.com/fxn/zeitwerk/issues/281 `const_source_location` keeps returning the location of the `autoload` call, even after the real constant was defined. It only starts returning the real constant location once the autoload was fully completed. ```ruby # /tmp/autoload.rb File.write("/tmp/const.rb", <<~RUBY) module Const LOCATION = Object.const_source_location(:Const) end RUBY autoload :Const, "/tmp/const" p Const::LOCATION ``` Expected Output: ```ruby ["/tmp/const.rb", 1] ``` Actual Output: ```ruby ["/tmp/autoload.rb", 8] ``` Potential patch: https://github.com/ruby/ruby/pull/9549 -- 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/postorius/lists/ruby-core.ml.ruby-lang.org/