Project

General

Profile

Actions

Bug #17354

closed

Module#const_source_location is misleading for constants awaiting autoload

Added by tomstuart (Tom Stuart) about 4 years ago. Updated about 1 year ago.

Status:
Closed
Assignee:
-
Target version:
-
ruby -v:
ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-darwin20]
[ruby-core:101141]

Description

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 92730810 and backported to v2_7_2 in 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? 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 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.

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like1Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0