How to call the methods of a delegator from the wrapped object in Ruby
Asked Answered
B

0

6

Let's say I have this class and delegator

class MyObject
  def foo
    "foo #{bar}"
  end 

  def bar
    "bar"
  end
end

class MyDelegator < SimpleDelegator
  def bar
    "decorated bar"
  end
end

MyDelegator.new(MyObject.new).foo # => "foo bar"

This obviously happens because of the method resolution chain. #foo is not found on the MyDelegator class, therefore it is delegated to the MyObject class. When MyObject#foo is called, the method in turn calls MyObject#bar.

I can have MyDelegator#foo return "foo decorated bar" this way:

class MyObject
  def foo
    "foo #{bar}"
  end 

  def bar
    "bar"
  end
end

class MyDelegator < SimpleDelegator
  module MyMethods
    def bar
      "decorated bar"
    end
  end

  def initialize(object)
    super
    object.singleton_class.include(object)
  end
end

MyDelegator.new(MyObject.new).foo # => "foo decorated bar"

I could also have defined methods on the eigenclass of the MyObject instance using define_method or instance_eval for example. My question is the following:

Is there a way I can achieve the same thing without changing the eigenclass of the wrapped object and without cloning it while keeping the wrapped object untouched for other consumers of the object downstream?

Bent answered 12/4, 2018 at 23:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.