Can someone please provide some insight as to when to use delegation via
Seller < DelegateClass(Person)
Seller < Person
class Seller < DelegateClass(Person)
class Seller < Person
There are a couple of differences that can help provide insight as to which approach to use.
The following examples build on this silly hypothetical:
If you're building on top of
Fixnum, you're safer using
DelegateClass (or another delegator). For more on why, Steve Klabnik's cautioning is a good place to start).
This makes it easier to accept an instance of a general object and make it behave in a way that's specific to your implementation:
class Message < DelegateClass(String); def print upcase end end # […] def log(message) message = Message.new(message) unless message.is_a?(Message) end
DelegateClasssubclasses expect an instance of the delegated class as an argument to
This can make it tricky to “subclass” classes that you're handing to library code. For example, this is a fairly common practice that won't work out of the box with
class MyLogger < DelegateClass(ActiveSupport::Logger); end Foo::ThirdParty::Library.configure do |c| c.logger = MyLogger # no good end
This doesn't work because our library expects to behave like most loggers and instantiate without arguments. This can be addressed by defining
initialize and creating an instance of
ActiveSupport::Logger, but probably not the right solution in this case.