Note that there are some explanatory texts on larger screens.

plurals
  1. PODelegator through BasicObject transparency
    text
    copied!<p><strong>Context</strong>: I am trying to put up a Decorator pattern in Ruby. As a Decorator should delegate all unknown methods to the underlying objects, I used the Delegator class. I could have used SimpleDelegator but I wanted to fully understand what I was doing.</p> <p>So the basic code I came out with was :</p> <pre><code>class Decorator &lt; Delegator def initialize(component) super @component = component end def __setobj__(o); @component = o end def __getobj__; @component end def send(s, *a); __send__(s, *a) end end </code></pre> <p>Which is ~exactly the same as the implementation of SimpleDelegator. Seems good.</p> <p>But the thing I did not want was for the code handling the Decorator to know it is manipulating a Decorator. I want full transparency.</p> <p>At this moment <code>Decorator.new(Object.new).class</code> returned <code>Decorator</code></p> <p>So I tinkered a bit and came up with this :</p> <pre><code>class Decorator &lt; Delegator undef_method :== undef_method :class undef_method :instance_of? # Stores the decorated object def initialize(component) super @component = component end def __setobj__(o); @component = o end def __getobj__; @component end def send(s, *a); __send__(s, *a) end end </code></pre> <p>This way, I can safely use <code>class</code> or <code>instance_of?</code> on my Decorated object, it will send the method to the underlying object via method_missing (which is implemented by Delegator).</p> <p>The thing is : I don't understand why I had to undef <code>:class</code> and <code>:instance_of?</code>. I can see that BasicObject defines <code>:==</code> so I had to undefine it but what about those two ? I looked at the BasicObject documentation and a bit in the C code but did not find anything. I looked the same at the Delegator documentation and code, and did not find anything either. It seems Delegator include the Kernel module, but Kernel#class or Kernel#instance_of? don't exist.</p> <p>Where those two method came from ? Why did I need to undefine them if they were not implemented at all ? I guess I must be missing something about Ruby's object model or something.</p> <p>Thanks.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload