奇怪的SimpleDelegator行为

时间:2013-08-10 16:19:55

标签: ruby delegation

我的代码使用SimpleDelegator

require 'delegate'

class Foo < SimpleDelegator
  def meth
    p 'new_meth'
  end
end

class Bar
  def meth
    p 'old_meth'
  end

  def bar_meth
    meth
  end
end

bar = Bar.new
foo = Foo.new(bar)
foo.meth      #=> "new_meth"
foo.bar_meth  #=> "old_meth"

为什么最后一行给出"old_meth" ??? !!!谢谢!

1 个答案:

答案 0 :(得分:4)

Delegator说:

  

此库提供了三种不同的方法来将方法调用委托给对象。最容易使用的是 SimpleDelegator 将对象传递给构造函数,并且将委派对象支持的所有方法。 此对象可以在以后更改。

好的,现在看一下输出,它位于符号# =>的右侧。

require 'delegate'

class Foo < SimpleDelegator
  def meth
    p 'new_meth'
  end
end

class Bar
  def meth
    p 'old_meth'
  end

  def bar_meth
    self.method(:meth)
  end
end

bar = Bar.new # => #<Bar:0x8b31728>
foo = Foo.new(bar)
foo.__getobj__ # => #<Bar:0x8b31728>
foo.bar_meth # => #<Method: Bar#meth>
foo.method(:meth) # => #<Method: Foo#meth>

因此,当我使用行foo.method(:meth)时,输出(#<Method: Foo#meth>)确认无论何时调用foo.methmeth Foo方法foo.bar_meth将调用类。但是行#<Method: Bar#meth>输出(bar_meth)只是在方法meth内,如果您调用Bar#meth方法,那么foo将会被调用。

SimpleDelegator说:

  

Delegator的一个具体实现,该类提供了将所有支持的方法调用委托给传递给构造函数的对象的方法,甚至可以在以后使用# setobj 更改委派给的对象。

是的,在您的情况下bar对象已设置为#__setobj__对象,使用foo.__getobj__。第{{1}}行的输出显示为。