我希望Ruby的消息传递基础设施意味着可能会有一些聪明的技巧来解决这个问题。
我该如何确定调用对象——即调用当前方法的对象是什么?
你可以通过以下方法轻松查看调用感兴趣函数的代码行:
caller.first
这将告诉您调用相关函数的文件名和行号。然后,您可以反向计算出是哪个对象。
然而,看起来你更想知道调用某个函数的对象,可能是在一个实例方法内部。我不知道有没有一种方法来解决这个问题 - 但我不会使用它,因为它似乎严重违反了封装性原则。
binding_of_caller
gem可以让你在调用栈上的任何调用者的上下文中执行代码(调用者、调用者的调用者等)。它在开发中用于检查(读取在调用栈上的任何位置执行任何操作)调用栈,如在better_errors
中使用。
我应该提到,这种技术仅应用于调试、娱乐或教育目的,因为它严重违反了面向对象编程原则。
Binding
类的对象封装了代码中某个特定位置的执行上下文,并保留此上下文以供将来使用。
eval
。require 'binding_of_caller' # I assume, you installed this gem already?
0
)调用方实例:binding.of_caller(0).eval('self')
...或者甚至是一个立即调用的方法:
binding.of_caller(0).eval('__method__')
0
以外的数字来获取调用者的绑定。
非常的hacky。但是如果您真的需要这个,那就用吧。
科技的最高水平:
1 # phone.rb
2 class Phone
3 def caller_id
4 caller
5 end
6 end
7
8 class RecklessDriver
9 def initialize
10 @phone = Phone.new
11 end
12 def dial
13 @phone.caller_id
14 end
15 end
16
17 p = Phone.new
18 p.caller_id.inspect # => ["phone.rb:18:in `<main>'"]
19
20 macek = RecklessDriver.new
22 macek.dial.inspect # => ["phone.rb:13:in `dial'", "phone.rb:22:in `<main>'"]
注意:示例行号。 phone.rb:X
指的是脚本的第X
行。
看看 phone.rb:13
!这个 dial
方法才是发起电话呼叫的方法!而 phone.rb:22
则指向使用了 dial
方法的鲁莽驾驶者!
Peter的答案在生产代码示例中使用
在我们公司中,我们正在废弃deleted
标志,改用Paranoia gem的deleted_at
列。下面的代码是我们如何确保在删除列之前一切都会顺利进行(部署此代码,然后在实时状态下经过2或3天后,我们部署迁移remoove_column:lessons,:deleted
)
class Lesson < ActiveRecord::Base
def deleted
if caller.select { |c| c.match /serialization\.rb/ }.any?
# this is Rails object mapping
!!deleted_at
else
raise 'deplicated - deleted was replaced by deleted_at'
end
end
end
self
这样吗?irb> class Object
.. def test
.. self
.. end
.. end
=> nil
irb> o = Object.new
=> #<Object:0xb76c5b6c>
irb> o.test
=> #<Object:0xb76c5b6c>
test()
函数中的问题,OP 想要获取在 irb 中输入 self
后得到的对象。 - lulalala
self
。 - Peter