`gf` finding files with nested constant
jweir opened this issue · comments
Could gf
be less explicit in finding files?
For example if file foo.rb
is defined as
module Foo
VALUE=1
module Bar; end
end
gf
on Foo::Bar
will report file not found. What, would be nice is if gf
would walk up the directory tree and find foo.rb
This also applies to gf
over module/classes with a constant
gf
on Foo::VALUE
will also report file not found.
The answer is yes, with a couple of asterisks. The way gf
works is we build a relative filename, the same filename that you would pass to require
to explicitly load the library, and feed it to :find
, which makes it absolute by looking through 'path'
, or gives an error if it can't be found. Without changing that, our only real option is to preemptively hunt for the file, and if we can't find it, remove one level of filename and try again. Here's how I did basically that for Lua:
A downside of this approach is that we're now doing two searches through the load path on every gf
, more if the file can't be found. This is a bigger deal for the long load paths of a Rails app than it is for Lua. For one additional search, I am seeing an additional overhead of about 40ms on the random Rails app I loaded.
My other concern is that it takes what was previously a simple deterministic process of translating a class name to a file name and throws in a giant dependency on the state of the current file system, making it much harder to reason about. This isn't unprecedented - we're already doing it for asset and view extensions - but now we're taking it a one step further and changing the base filename.
Between these two, I'm on the fence. But as a sponsor (thanks!), you've won me over. I'm only going to go one level deep: Foo::Bar::VALUE
will only get walked back to foo/bar.rb
. I think that strikes a reasonable balance.