Strange behavior of SimpleDelegator

Have 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 does the last line give "old_meth" ??? !!! Thanks!

+4
source share
1 answer

Delegator :

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

So now look at the output 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 string foo.method(:meth) , then the output ( #<Method: Foo#meth> ) confirms that whenever you call foo.meth , then the meth method of the Foo class will be called. But the line foo.bar_meth > exits ( #<Method: Bar#meth> ), simply saying that inside the bar_meth method, if you call the meth method, then Bar#meth will be called.

SimpleDelegator :

A specific delegation implementation, this class provides the ability to delegate all supported method calls to the object passed to the constructor, and even modify the object delegated later using # setobj .

Yes, in your case, the Foo object was set to the bar object using #__setobj__ . The output of the string foo.__getobj__ shows that.

+4
source

Source: https://habr.com/ru/post/1496325/


All Articles