有什么方法可以确定哪个对象叫做方法?

时间:2010-04-24 03:43:24

标签: ruby messaging introspection dynamic-languages

我希望Ruby的消息传递基础设施意味着可能有一些聪明的技巧。

如何确定调用对象 - 哪个对象称为我当前使用的方法?

5 个答案:

答案 0 :(得分:13)

您可以通过

轻松查看调用感兴趣功能的代码行
caller.first

它会告诉你调用相关函数的文件名和行号。然后你可以反算它是哪个对象。

但是,听起来你更像是某个调用某个函数的对象,可能是在一个实例方法中。我不知道一种解决这个问题的方法 - 但我还是不会使用它,因为它似乎严重违反了封装。

答案 1 :(得分:6)

作为一个选项,有一个binding_of_caller gem允许您在调用堆栈上的任何调用者(调用者,调用者的调用者等)的上下文中执行代码。它对于在better_errors中使用的检查(在调用堆栈中读取在调用堆栈中的任何位置执行任何操作)调用堆栈非常有用。

  

Binding的对象将执行上下文封装在代码中的某个特定位置,并保留此上下文以供将来使用。

     

- http://www.ruby-doc.org/core-2.1.4/Binding.html

我应该提一下,这种技术应该只用于调试,娱乐或教育目的,因为它严重违反了OOP的原则。
主要是因为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。但是,如果你真的需要这个 - 你去吧。

答案 2 :(得分:2)

最好的技术:

 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方法的鲁莽驱动程序!

答案 3 :(得分:1)

你的意思是self

irb> class Object
  ..   def test
  ..     self
  ..   end
  .. end
  => nil
irb> o = Object.new
  => #<Object:0xb76c5b6c>
irb> o.test
  => #<Object:0xb76c5b6c>

答案 4 :(得分:1)

彼得在生产代码示例中使用的answer

在我的公司,我们在Paranoia gem deleted列的风格中弃用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