Feature #8751
openAdd offsets to method#source_location
Description
Hello,
I would like to have byte offsets returned on the source_location for methods. For example:
def foo(&b)
b.source_location # => [file_name, line_number, start_byte, end_byte]
end
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 11 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
For example:
x = SomeObject.new
add_a_monkey_patch
x.method(:some_method).source # => 'def some_method; ...; end'
Updated by banister (john mair) over 11 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 ko1 (Koichi Sasada) over 11 years ago
Maybe it is easy to extend Proc#source_location and easy to know locations of chaining blocks.
foo{...}.bar{...}.baz{...}
Blocks are in same line and difficult to know which block is.
Updated by rocky (Rocky Bernstein) over 11 years ago
=begin
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.
=end
Updated by hsbt (Hiroshi SHIBATA) almost 3 years ago
- Project changed from 14 to Ruby master
Updated by Eregon (Benoit Daloze) about 2 months ago
- Related to Feature #17930: Add column information into error backtrace added