When to use Ruby DelegateClass instead of SimpleDelegator? (DelegateClass method vs. SimpleDelegator class)
Asked Answered
D

1

30

Probably i am missing something simple, but i do not understand how to use Ruby's DelegateClass method, i mean when to use it instead of SimpleDelegator class. For example, all of the following seem to work mostly identically:

require 'delegate'

a = SimpleDelegator.new([0])
b = DelegateClass(Array).new([0])
c = DelegateClass(String).new([0])
a << 1
b << 2
c << 3
p a # => [0, 1]
p b # => [0, 2]
p c # => [0, 3]

Note that it does not seem to matter which class is passed to DelegateClass.

Dispart answered 27/10, 2012 at 23:2 Comment(1)
After thinking about it for some time, the whole Delegator Pattern looks to me like a quick dirty hack :). You send a message, and you do not know which class will be responsible for answering. The delegator passes through all the messages it does not recognize without knowing if and how they will be answered (otherwise it could be realised as a subclass, or use composition, couldn't it?). The original class does not really control anything anymore and does not even know there is a delegator between it and the rest of the world.Dispart
A
22

Use subclass SimpleDelegator when you want an object that both has its own behavior and delegates to different objects during its lifetime.

Essentially saying use DelegateClass when the class you are creating is not going to get a different object. TempFile in Ruby is only going to decorate a File object SimpleDelegator can be reused on different objects.

Example:

require 'delegate'


class TicketSeller
  def sellTicket()
    'Here is a ticket'
  end
end


class NoTicketSeller
  def sellTicket()
    'Sorry-come back tomorrow'
  end
end


class TicketOffice < SimpleDelegator
  def initialize
    @seller = TicketSeller.new
    @noseller = NoTicketSeller.new
    super(@seller)
  end
  def allowSales(allow = true)
    __setobj__(allow ? @seller : @noseller)
    allow
  end
end

to = TicketOffice.new
to.sellTicket   »   "Here is a ticket"
to.allowSales(false)    »   false
to.sellTicket   »   "Sorry-come back tomorrow"
to.allowSales(true)     »   true
to.sellTicket   »   "Here is a ticket"

Here is another good explanation a-delegate-matter

Anthropology answered 12/11, 2012 at 21:16 Comment(1)
You shouldn't reuse a SimpleDelegator for different types of objects, though it's ok to reuse for different instances; the docs explicitly say about #__setobj__: "It’s important to note that this does not cause SimpleDelegator’s methods to change. ... you probably only want to change delegation to objects of the same type as the original delegate."Exospore

© 2022 - 2024 — McMap. All rights reserved.