Project

General

Profile

Actions

Feature #14836

closed

Method to return first/last lineno/column of Proc

Added by tagomoris (Satoshi Tagomori) almost 6 years ago. Updated over 5 years ago.

Status:
Closed
Assignee:
-
Target version:
-
[ruby-core:87456]

Description

As written in https://bugs.ruby-lang.org/issues/6012, we want to know column no of Proc location.
In addition to it, I want to know the last_lineno and last_column.

If we don't have these values, we cannot know whether the "a" in code below is defined in block, or not.

b1 = ->(){ foo() }; a = 1; b2 = ->(){ bar() }

Updated by joker1007 (Tomohiro Hashidate) almost 6 years ago

I want this feature too.

I wrote a rubygem that parses proc and converts to AST::Node (of ast gem).
To inspect proc source code is main purpose.

https://github.com/joker1007/proc_to_ast

Usage example.

# this is sample of rspec-parameterized gem

  describe "lambda parameter" do
    where(:a, :b, :answer) do
      [
        [1 , 2 , -> {should == 3}],
        [5 , 8 , -> {should == 13}],
        [0 , 0 , -> {should == 0}]
      ]
    end

    with_them do
      subject {a + b}
      it "should do additions" do
        self.instance_exec(&answer)
      end
    end
  end

And output example.

  lambda parameter
    a: 1, b: 2, answer: -> {should == 3}
      should do additions
    a: 5, b: 8, answer: -> {should == 13}
      should do additions
    a: 0, b: 0, answer: -> {should == 0}
      should do additions

But the gem has very heuristic hacks and it is fragile.
If multi procs exist at same line, it is very difficult to detect particular proc.
Accurate Proc location resolves the probrem.

Updated by yui-knk (Kaneko Yuichiro) over 5 years ago

If you use location information of proc to get AST nodes, I feel adding class method to AST module which receives proc and return AST nodes directly is useful.
What do you think about it?

For example:

def a(&block)
  node = RubyVM::AST.of(block)
  p node
  p node.children
  p node.children.last.children
end

a do
  1 + 2
  "abc".upcase
end
$ ./miniruby /tmp/of.rb
#<RubyVM::AST::Node(NODE_SCOPE(0) 8:2, 11:3): >
[[], nil, #<RubyVM::AST::Node(NODE_BLOCK(1) 9:2, 10:14): >]
[#<RubyVM::AST::Node(NODE_OPCALL(36) 9:2, 9:7): >, #<RubyVM::AST::Node(NODE_CALL(35) 10:2, 10:14): >]

Ref: https://github.com/ruby/ruby/compare/trunk...yui-knk:feature/ast_of?expand=1

Updated by joker1007 (Tomohiro Hashidate) over 5 years ago

Great work!!
What I want is this!
If ruby-trunk merges this patch, I will try to use.

Actions #4

Updated by yui-knk (Kaneko Yuichiro) over 5 years ago

  • Status changed from Open to Closed

Applied in changeset trunk|r65542.


Implement RubyVM::AST.of [Feature #14836]

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0