Given a class like:
class Thing
CONSTANT = 10
# other code
end
And another like:
class Other
def initialize
@thing = Thing.new
end
def method
puts CONSTANT
end
end
Is it possible to extend Forwardable
to have Other
's CONSTANT
delegate to Thing
's constant?
I have tried extendingSingleForwardable
(see docs here ) like so:
class Other
extend SingleForwardable
def initialize
@thing = Thing.new
end
def method
puts CONSTANT
end
def_single_delegator :@thing, :CONSTANT
end
and:
def_single_delegator :@thing, :constant
but neither worked, am I getting the syntax wrong? If not, is there another way?
This one is answered by the documentation (bold emphasis mine):
def_single_delegator(accessor, method, new_name=method)
Defines a method method which delegates to accessor (i.e. it calls the method of the same name in accessor). If new_name is provided, it is used as the name for the delegate method.
So, no, you can only delegate message sends, not constant lookup.
Forwardable (and SingleForwardable) let you add class functions to your current class via a module. When you write a delegator you're specifying which methods are being passed on to the receiving object from the original module.
In your example, def_single_delegator :@thing, :CONSTANT
is being interpreted as the following: Defines a method :CONSTANT
which delegates to accessor :@thing
(i.e. it calls the method of the same name in accessor).
As you can see, this is not passing on the value of the constant, instead it's passing on a method with the same name as the constant. If you want to pass on the same value as the constant you can provide an accessor method that returns to you the value of the original constant so that you can assign it in this class.