I have a class with roughly the following structure:
class X
def initialize
@container = Container.new
....
end
def store
@container.get_store
end
def f
store.f
end
def g
store.g
end
def h
store.h
end
....
end
As can be seen, I have a couple of methods, which simply "forward" to store, only that store is not an instance variable, but the result of a parameterless method. Is there a compact way to implement this forwarding? If store
would always return the identical object, I could do something like this:
class X
extend Forwardable
def initialize
container = Container.new
@store = container.the_store
end
def_delegator :@store, .f, :g, :h
end
but I can't rely on this; @container.the_store
may change during the lifetime of the instance. One alternative I considered is something like
class X
[:f,:g,:h].each do |meth_sym|
define_method(meth_sym) do |*args|
store.public_send(meth_sym, *args)
end
end
def store
@container.get_store
end
end
but this looks clumsy. Can anymody suggest a different solution for my problem?
CodePudding user response:
From the docs for Forwardable#def_instance_delegator
:
accessor
should be a method name, instance variable name, or constant name.
Examples: (both symbols and strings work and .
is equivalent to ::
)
def_delegator :@store, :f # delegates f to instance variable @store
def_delegator :store, :f # delegates f to instance method store
def_delegator 'X.store', :f # delegates f to class method store
def_delegator 'X::Store', :f # delegates f to constant X::Store
Since you have an instance method, you want :store
(without @
)