[ruby-core:124433] [Ruby Feature#6012] Proc#source_location also return the column
Issue #6012 has been updated by Eregon (Benoit Daloze). mame (Yusuke Endoh) wrote in #note-45:
First, I suspect that what many users of `method_source` gem actually need is the AST.
Many yes but not all, maybe even only a minority (see below). The fact there is `Method#source` indicates that some usages only want the code, and don't need to parse it. If it was all, there likely wouldn't be `Method#source`, but another method to return the (e.g. parser gem) AST directly then. A quick search shows some examples which do not use an AST: https://github.com/search?q=language%3ARuby+%2F%28method%7Cmeth%29%5C.source%5Cb%2F&type=code ```ruby # spree/spree obj_method.source.squish[/(expect *({|do) *)(.*?)( *(}|end).(not_)*to)/, 3] # evilmartians/terraforming-rails, perfect use case for end_line in source_location # Uses `method_source` to get the source code and the number of lines meth.source_location.last..(meth.source_location.last + meth.source.lines.size) # pry/pry-git final_code = before_code << meth.source.lines.to_a << after_code # Darkmux/cyberspy, seems pry related, makes sense to be able to show the source of a method/block in a REPL new(meth.source, start_line, meth.source_type) # rambler-digital-solutions/rusby, the preprocessor acts on the code String, not an AST Preprocessor.apply(orig_method.source), # tdg5/tco_method code = <<-CODE #{receiver_class} #{receiver.name} #{existing_method.source} end CODE # garmoshka-mo/pry-moves, perfect use case for end_line in source_location end: (source[1] + method.source.count("\n") - 1) # SyborgStudios/overrides_tracker def self.outdented_method_body(method) body = method.source indent = body.match(/^\W+/).to_s # rpanachi/core_ext, perfect use case for end_line in source_location end_line = method.source.count("\n") + start_line - 1 # annkissam/scryglass method_lines = Hexes.capture_io { puts method.source }.split("\n") # callstacking/callstacking-rails, seems like it adds extra code to instrument, no AST, no dependency on parser method_source = method(__method__).super_method.source if settings.analyze_source? # jeromedalbert/rubocop-obsession corrector.replace(method, method.source.sub(method.method_name.to_s, 'perform')) # geni/sweatshop, perfect use case for end_line in source_location end_line = method.source.count("\n") + start_line + 1 # Auralcat/my-dotfiles # Display source code quickly in IRB. def srd(method) method.source.display end ``` and that's only the examples from the first page. In fact a majority of the matches in that first page seem to not use an AST, so I'm not even sure the majority of uses cases need the AST. Finding the `end_line` of a method seems a recurrent need, this is now provided with the extended `source_location`. ---
However, `source_location` is not an appropriate key to look up the AST subtree corresponding to a Ruby object.
I believe it is though, with the knowledge of what kind of node we are looking for. For example in `def foo; bar; end`, `bar` in the AST is covered exactly by both a `StatementsNode` and a `CallNode`. If we are using `Thread::Backtrace::Location#ast` we'd want the location of the call to `bar`, so we know we want the `CallNode`, not the `StatementsNode` and there is no ambiguity. I believe the same holds for all 5 methods proposed in #21795. My intuition there is all nodes listed in https://bugs.ruby-lang.org/issues/21795#note-2 cannot have the exact same `source_location` (e.g. we cannot have code with the same starting and ending position that is two of `DefNode`, `LambdaNode`, `ForNode`, `Call*Node`, `Index*Node`, `YieldNode`). Do you have a counter-example where this wouldn't hold? In fact if #21795 is accepted I do plan to implement it in TruffleRuby based on byte offsets in the source, which are equivalent to line+column start/end. ---------------------------------------- Feature #6012: Proc#source_location also return the column https://bugs.ruby-lang.org/issues/6012#change-115982 * Author: rogerdpack (Roger Pack) * Status: Closed * Assignee: nobu (Nobuyoshi Nakada) ---------------------------------------- As originally suggested in http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/42418 Suggestion/feature request: have #source_location also return the beginning column where it was defined. ["test.rb", 8, 33] Thanks! -roger- -- https://bugs.ruby-lang.org/
participants (1)
-
Eregon (Benoit Daloze)