获取调用特定全局方法的类和方法的列表

时间:2013-09-09 05:48:42

标签: ruby

我有一个名为$muffinize的方法,我想在我的代码中找到它的位置。换句话说,给出以下代码:

class A
    def foo
        $muffinize(1)
    end
    def bar
        ...
    end
end

class B
    def shoop
        $muffinize(2)
    end
    def woop
        ...
    end
end

class C
    def nope
        ...
    end
end

我想将结果写入(写入文件):

A:foo
B:shoop

我正在考虑使用正则表达式完成此任务,但我想知道是否有某种方法可以通过Ruby元编程实现这一点(我可能不小心将其用作流行语)?

3 个答案:

答案 0 :(得分:2)

Kernel.caller()将帮助您显示在运行时调用它的行号和方法。如果在松紧函数中放置puts caller(1,1)之类的东西,它将输出这些位置,但前提是它们在运行时被调用。

如果要进行离线源分析,则需要使用https://github.com/whitequark/parser之类的内容解析AST(抽象语法树)。

以下是ripper的一个快速示例(内置于新红宝石中) - 这不是严格意义上的AST,但它不提取类

#!/usr/local/env ruby

require 'ripper'
#require 'pry'

contents = File.open('example.rb').read

code = Ripper.lex(contents)
code.each do |line|
    if(line[1] == :on_ident and line[2] == "muffinize")
        puts "muffinize found at line #{line.first.first}"
    end
end

答案 1 :(得分:0)

通过ri获取类和方法列表,然后我可以使用method_source gem分析每个方法以检索其源代码,然后搜索muffinize。这并不排除muffinize出现在评论或字符串中的可能性,但我认为发生这种情况的可能性小到可以忽略。

答案 2 :(得分:0)

忽略你的代码在语法上甚至没有效率这一事实,这根本不可能。

这是一个简单的例子:

class A
  def foo
    bar
    muffinize(1)
  end
end
当且仅当A#foo终止时,

Object#muffinize才会致电bar。这意味着要弄清A#foo调用Object#muffinize是否需要解决暂停问题。