
Issue #17354 has been updated by mame (Yusuke Endoh). I said this could be useful for debugging. If a user finds a call to `autoload` on the line pointed to by `const_source_location`, they can guess that autoload is set. If they want to know the actual definition location, they can actually access it and then use `const_source_location`. The current behavior allows the user to choose these. In that sense, I think the current behavior is flexible. If `const_source_location` triggers autoload, not only is this flexibility lost, but loading may cause side effects, which may be inconvenient for a debugging purpose. ---------------------------------------- Bug #17354: Module#const_source_location is misleading for constants awaiting autoload https://bugs.ruby-lang.org/issues/17354#change-104567 * Author: tomstuart (Tom Stuart) * Status: Open * Priority: Normal * ruby -v: ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-darwin20] * Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN ---------------------------------------- Feature #10771 added `Module#const_source_location` as a way to find the source location of a constant’s definition. Bug #16764 reported that it didn’t work correctly for autoloaded constants, instead giving the source location of the `autoload` call site. This was fixed in `v3_0_0_preview1` in commit:92730810 and backported to `v2_7_2` in commit:c65aae11. However, `#const_source_location` still returns the `autoload` call site for constants which have not yet been loaded: ``` % echo 'class Foo; end' > foo.rb % irb
Module.const_defined?(:Foo) => false Module.const_source_location(:Foo) => nil
autoload :Foo, './foo' => nil
Module.const_defined?(:Foo) => true Module.const_source_location(:Foo) => ["(irb)", 3]
Module.const_get(:Foo) => Foo
Module.const_defined?(:Foo) => true Module.const_source_location(:Foo) => ["./foo.rb", 1]
This edge case is undocumented and surprising. It looks like a bug to the programmer who receives the `autoload` location instead of one of the documented return values of `#const_source_location` (`nil`, `[]`, or the definition’s source location).
We could either:
* change the behaviour of `#const_source_location` to return `[]` for constants awaiting autoload, which is consistent with the [return value of `Module#const_defined?`](https://docs.ruby-lang.org/en/2.7.0/Module.html#method-i-const_defined-3F) in this case (“if the constant is not present but there is an autoload for it, `true` is returned directly”), as well as the [return value of `#const_source_location`](https://docs.ruby-lang.org/en/2.7.0/Module.html#method-i-const_source_location) for other constants whose source location is unknown (“if the constant is found, but its source location can not be extracted (constant is defined in C code), empty array is returned”); or
* document the current behaviour of `#const_source_location` to make it less surprising.
I recommend the first option — although the current behaviour was recently specified in source:spec/ruby/core/module/const_source_location_spec.rb@6d059674#L209, it doesn’t seem intentional — but if that’s not feasible, simply documenting this edge case would also be an improvement.
--
https://bugs.ruby-lang.org/