从基于ruby的源文件中提取一段代码



我最近一直在玩flog,它很不错为ruby应用程序生成代码复杂性报告的工具。作为跑步的结果项目代码库上的flog,您将得到类似于以下内容的输出:

  1272.3: flog total
     7.3: flog/method average
    62.2: MyClass#foobar lib/myclass#foobar:123
    ... more similar lines ...
上面的

示例为方法提供了一个分数,并引用了方法中的精确行号定义该方法的源代码。这可以是一个普通的实例/类方法或任何其他"动态"方法,例如。Rake任务等

所以目标是从源代码中提取一段代码(很可能是一个方法)以在flog输出中定义的行号开始的文件。这个片段可以在某些web UI中用于显示各种代码度量(基于其他工具,如flay)和/或存储在数据库中。据我所知,这项任务涉及解析ruby代码转换成AST,然后遍历树查找相应的起始行和计算结束行号。我用这个库做了一些实验- https://github.com/whitequark/parser,大部分时间都有效,但它有点棘手得到正确的结果。

是否有其他的解决方案来快速地从源文件中提取方法代码在ruby中?

您可以实现通过名称或行号查找方法的功能。

这个示例代码展示了如何按名称查找方法代码。它很脏,但它可以工作(在Ruby 2.1.2上)。这是用parser (gem install parser)。

# method_finder.rb
require 'parser'
require 'parser/current'
class MethodFinder
  def initialize(filename)
@ast = parse(filename)
  end
  def find(method_name)
recursive_search_ast(@ast, method_name)
return @method_source
  end
  private
  def parse(filename)
Parser::CurrentRuby.parse(File.open(filename, "r").read)
  end
  def recursive_search_ast(ast, method_name)
ast.children.each do |child|
  if child.class.to_s == "Parser::AST::Node"
    if (child.type.to_s == "def" or child.type.to_s == "defs") and (child.children[0].to_s == method_name or child.children[1].to_s == method_name)
      @method_source = child.loc.expression.source
    else
      recursive_search_ast(child, method_name)
    end
  end
end
  end
end

你可以像下面这样使用MethodFinder

mf = MethodFinder.new("./method_finder.rb")
puts mf.find("find")
=> def find(method_name)
=>     recursive_search_ast(@ast, method_name)
=>     return @method_source
=>   end

最新更新