DelegateClass vs Class Inheritance in Ruby
Asked Answered
A

2

22

Can someone please provide some insight as to when to use delegation via DelegateClass (e.g. Seller < DelegateClass(Person)) and when to use class inheritance (e.g. Seller < Person) in ruby?

class Seller < DelegateClass(Person)
  def sales
     ...
  end 
end 

class Seller < Person 
  def sales
     ...
  end 
end 

When I was looking over the Ruby on Rails source on Github I found quite a few uses of DelegateClass.

Ardussi answered 6/8, 2016 at 21:44 Comment(0)
E
14

There are a couple of differences that can help provide insight as to which approach to use.

1) You can safely delegate to primitives (e.g. String), but cannot always safely inherit from them

If you're building on top of Hash or String or Fixnum, you're safer using DelegateClass (or another delegator). For more on why, Steve Klabnik's cautioning is a good place to start).

2) DelegateClass makes it easy to “convert” a more general object into a more specific one

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

3) A gotcha: DelegateClass subclasses expect an instance of the delegated class as an argument to new

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 DelegateClass:

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.

Embroider answered 6/8, 2016 at 22:41 Comment(0)
N
5

delegates model different behaviors of Person based on the context. e.g. the same person could be a seller in one context or a buyer in a different context. Inheritance is more rigid: a Bear and Tiger inherit from Animal, but an instance of Animal would never need to sometimes behave like a Bear and sometimes behave like a Tiger. An instance of a descendent of Animal is either one or the other.

Names answered 6/8, 2016 at 22:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.