There is my code using 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"

Why the last line gives "old_meth"???!!! Thanks!

有帮助吗?

解决方案

Delegator saying:

This library provides three different ways to delegate method calls to an object. The easiest to use is SimpleDelegator. Pass an object to the constructor and all methods supported by the object will be delegated. This object can be changed later.

Okay,so now look at the output,which is to the right of the symbol # =>.

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>

So when I used the line foo.method(:meth), then output(#<Method: Foo#meth>) confirms that whenever you will call foo.meth,then meth method of the Foo class will be called.But the line foo.bar_meth outputs(#<Method: Bar#meth>) simply saying that inside the method bar_meth,if you call meth method then, Bar#meth will be invoked.

SimpleDelegator saying that:

A concrete implementation of Delegator, this class provides the means to delegate all supported method calls to the object passed into the constructor and even to change the object being delegated to at a later time with #setobj.

Yes,in your case foo object has been set to bar object,by using #__setobj__. The output of the line foo.__getobj__ is showing that.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top