Add offsets to method#source_location
I would like to have byte offsets returned on the source_location for methods. For example:
b.source_location # => [file_name, line_number, start_byte, end_byte]
If we had the start and end byte for a method or proc, then we could find the source for methods and procs in each file. There are some cases (like with heredocuments) where the "end of the method" could be after the
end keyword. But I think if we just have offsets for the start of
def and the end of
end, I think it would cover 99% of usecases.
Updated by tenderlovemaking (Aaron Patterson) over 6 years ago
Sorry, I should have added some usecases to this description. I would like this feature mainly to:
- Extract source code from the source file so that I can: a) Show it on error pages b) Use ripper to parse and perform transformations on the methods c) Show the extracted source code to understand how a methods works in irb
x = SomeObject.new
x.method(:some_method).source # => 'def some_method; ...; end'
Updated by banister (john mair) over 6 years ago
We can already do a fairly reliable method extraction in Pry, we simply start reading from the first line of the method definition until we get a complete expression, there are a few situations where this breaks but in 90% of cases (in my experience) it works fine. Regarding (c), this is available already in Pry via the
show-source command (it also shows source for classes and modules, not just methods). I think it might be useful in some situations to get the column numbers but it's also not too difficult to just 'clean up' the source around the method source_location in cases where the method definition is preceded by other code on the same line.
We also implemented Method#source in the method_source gem: https://github.com/banister/method_source
Updated by rocky (Rocky Bernstein) over 6 years ago
Although I think some other suggestion will be used if this issue gets addressed, I want to mention a cool implementation for representing source-code positions. I believe it would the right approach to take if things were done from scratch.
The Go language has a compact way to represent a source code position (file, line and column) in a single (32-bit) word. See ((URL:http://golang.org/pkg/go/token/#Pos)). If you look at how that is implemented, it can can trivially be extended to source-code ranges as well.