如何获得调用方法的名称?


161

Ruby中有没有一种方法可以在方法内部找到调用方法的名称?

例如:

class Test
  def self.foo
    Fooz.bar
  end
end

class Fooz
  def self.bar
    # get Test.foo or foo
  end
end



与“获取Ruby中当前执行的方法的名称”不重复。这个问题要求调用方法的名称,而不是当前方法的名称。
韦恩·康拉德,

Answers:


210
puts caller[0]

也许...

puts caller[0][/`.*'/][1..-2]

5
是的,请参阅Kernel#caller,又名ruby-doc.org/core-1.8.7/classes/Kernel.html#M001073
DigitalRoss 2011年

10
这给出了调用方法的名称,但没有给出该方法属于哪个模块或类的任何指示。那可能吗?
thomthom

@thomthom是的,这是可能的,你可以调用self.class.name看到类的名称
索林

regex很好地用作字符串索引!也可以使用caller[0][/`(.*)'/,1]
aks

1
这在Rails 5.2.1中似乎不起作用。在Rails控制器中,返回"block in make_lambda"。我猜这仅适用于Ruby。
dcangulo

164

在Ruby 2.0.0中,您可以使用:

caller_locations(1,1)[0].label

它比Ruby 1.8+解决方案快得多

caller[0][/`([^']*)'/, 1]

backports当我有时间(或请求请求!)时,将包含在其中。


值得注意的是,Rubinius中没有此功能。
Max

1
如果您使用pry,则您必须忽略pry stacktrace……似乎没有默认的解决方案。
dtc

6
现在看来是caller_locations[0].label在Ruby 2.2.0上,否则您始终会有send_action结果
brcebn16年

1
我们如何才能只调用app方法而忽略框架调用?
矩阵

31

使用caller_locations(1,1)[0].label(对于红宝石> = 2.0)

编辑:我的回答是说要使用,__method__但我错了,它返回当前方法名称。


1
@OswaldoFerreira谢谢,在某处的另一个答案中找到了它
Dorian

5
这是不正确的,它返回当前方法,而不是调用当前方法的方法...
thrice801

1
奇迹般有效。似乎也比2.0版之前的方法快得多。
Dr.Strangelove

21

我用

caller[0][/`([^']*)'/, 1]

4
与DigitalRoss的方法相比,此方法有什么优势?
安德鲁·格林

2
更清洁,更精确。而不是进行搜索,而是使用数组方法根据位置拆分不需要的字符(这可能是错误的)。
新亚历山大(亚历山大)

2
为什么不简单地使用caller [0] [/`(。*)'/,1]?我不是正则表达式专家,但它似乎有效。
collimarco 2012年

7
@collimarco只要字符串不包含'您要查找的字符串(我想不能),结果肯定是相同的。但是,[^']*由于regex引擎在到达表达式的那一刻就停止尝试与该部分匹配'(您的版本将到达末尾,然后回溯,因为'在末尾找不到a),因此其性能会更好。当然,在这种情况下,差异几乎可以忽略不计,但是.在可能的情况下,避免使用正则表达式是一个好习惯。
Thor84no 2012年

4

怎么样

caller[0].split("`").pop.gsub("'", "")

更加干净的imo。


3

相反,您可以将其编写为库函数,并在需要时进行调用。代码如下:

module CallChain
  def self.caller_method(depth=1)
    parse_caller(caller(depth+1).first).last
  end

  private

  # Copied from ActionMailer
  def self.parse_caller(at)
    if /^(.+?):(\d+)(?::in `(.*)')?/ =~ at
      file   = Regexp.last_match[1]
      line   = Regexp.last_match[2].to_i
      method = Regexp.last_match[3]
      [file, line, method]
    end
  end
end

要触发上述模块方法,您需要这样调用: caller = CallChain.caller_method

来自的代码参考


1
始终欢迎潜在解决方案的链接,但是请在该链接周围添加上下文,以便您的其他用户会知道它的含义和存在的原因。如果目标站点无法访问或永久脱机,请始终引用重要链接中最相关的部分。考虑到为什么仅仅是删除一个外部站点的链接以及为什么删除某些答案的可能原因
XaviLópez

@XaviLópez更新了答案,请纠正如果做错了什么或有什么误会……thnx提出了这样的建议:)
Amit karsale 2014年

1
感谢您改善答案。不幸的是,我对Ruby没有足够的知识,无法对这篇文章发表评论,但是现在的答案似乎还不错。我已删除我的否决票。祝您好运:-)
哈维·洛佩斯

2

为了查看任何语言的调用方和被调用方信息,无论是ruby还是java或python,您都希望查看堆栈跟踪。在某些语言(例如Rust和C ++)中,编译器内置了一些选项,可以打开您可以在运行时查看的某些概要分析机制。我确实相信Ruby存在一种叫做ruby-prof的东西。

如上所述,您可以查看执行堆栈中的ruby。该执行堆栈是一个包含回溯位置对象的数组。

基本上,您需要了解的有关此命令的所有信息如下:

调用方(开始= 1,长度=无)→数组或无

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.