2011-02-24 53 views
116

有没有一种方法可以在Ruby中查找方法内的调用方法名称?如何获取调用方法的名称?

例如:

class Test 
    def self.foo 
    Fooz.bar 
    end 
end 

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

的[可能重复获取当前正在执行的方法的名称在Ruby中](http://stackoverflow.com/questions/199527/get-the-name-of-the-currently-executing-method-in-ruby) – 2013-02-25 08:37:42

+0

获取调用对象:http://stackoverflow.com/questions/2703136/any-way-to-determine-which-object-called-a-method – 2014-09-10 21:54:37

回答

163
puts caller[0] 

或许......

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

这真的有用吗? – 2011-02-24 04:26:46

+4

是的,请参阅Kernel#caller,aka http://www.ruby-doc.org/core-1.8.7/classes/Kernel.html#M001073 – DigitalRoss 2011-02-24 04:29:49

+0

非常感谢!:) – jrichardlai 2011-02-24 04:34:42

20

我用

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

这比DigitalRoss的方法有什么优势? – 2012-06-19 06:36:50

+2

更清洁,更精确。而不是搜索,然后使用数组方法根据位置分割不需要的字符(可能不正确)。 – 2012-07-09 21:12:57

+2

为什么不简单地使用调用者[0] [/'(。*)'/,1]?我不是关于正则表达式的大师,但它似乎工作。 – collimarco 2012-07-18 09:56:21

129

在Ruby 2.0.0,你可以使用:

caller_locations(1,1)[0].label 

much faster比红宝石1.8+解决方案:

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

将获得包含在backports,当我得到的时间(或拉的请求!)。

+0

感谢哥们,正是我需要的。 – mhenrixon 2013-06-11 22:24:16

+0

值得注意的是,这在Rubinius中不可用。 – Max 2014-05-04 22:29:22

+0

如果你使用pry,你必须忽略pry stacktrace它似乎...似乎没有一个默认的解决方案。 – dtc 2015-09-24 06:18:27

20

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

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

+0

最佳答案! – 2014-01-20 23:03:30

+1

@OswaldoFerreira谢谢,在另一个回答某处发现它在SO上 – Dorian 2014-01-20 23:35:11

+3

这是不正确的,它返回当前的方法,而不是调用当前方法的方法... – thrice801 2014-04-09 20:57:48

4

如何

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

干净多了海事组织。

+0

作品https://gist.github.com/Dorian/f8a276bebfc35ff01838 – Dorian 2014-06-10 19:08:27

1

相反,您可以将其编写为库函数并在需要时拨打电话。代码去如下:

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

code reference from

+1

总是欢迎指向潜在解决方案的链接,但请[在链接附近添加上下文](http://meta.stackoverflow.com/a/8259/ 169503),所以你的用户会有一些想法是什么,为什么它在那里。如果目标网站无法访问或永久离线,请始终引用重要链接中最相关的部分。考虑到_barely不仅仅是一个链接到外部网站_是一个可能的原因[为什么和如何删除一些答案?](http://stackoverflow.com/help/deleted-answers)。 – 2014-04-29 12:16:42

+0

@XaviLópez已更新答案,请纠正如果我做错了或错误的东西... thnx的那种建议:) – 2014-05-02 05:08:20

+1

感谢您提高您的答案。不幸的是,我没有足够的关于Ruby的知识来正确评论这篇文章,但现在答案看起来很好。我已经删除了我的downvote。好运 :-) – 2014-05-02 07:35:40

2

为了看到主叫方和被叫方信息的任何语言,无论是ruby还是java或python,你总是会想看看栈跟踪。在某些语言中,如Rust和C++,编译器中内置了一些选项,用于打开某些在运行时可以查看的概要分析机制。我相信红宝石存在一种称为ruby-prof的方式。

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

基本上所有你需要了解这个命令如下:

呼叫者(开始= 1,长度=无)→阵列或零