class SimpleDelegator

Eine konkrete Implementierung von Delegator, diese Klasse bietet die Mittel, um alle unterstützten Methodenaufrufe an das im Konstruktor übergebene Objekt zu delegieren und sogar das zu delegierende Objekt später mit __setobj__ zu ändern.

class User
  def born_on
    Date.new(1989, 9, 10)
  end
end

require 'delegate'

class UserDecorator < SimpleDelegator
  def birth_year
    born_on.year
  end
end

decorated_user = UserDecorator.new(User.new)
decorated_user.birth_year  #=> 1989
decorated_user.__getobj__  #=> #<User: ...>

Eine SimpleDelegator-Instanz kann den Vorteil nutzen, dass SimpleDelegator eine Unterklasse von Delegator ist, um super aufzurufen, damit Methoden auf dem delegierten Objekt aufgerufen werden.

class SuperArray < SimpleDelegator
  def [](*args)
    super + 1
  end
end

SuperArray.new([1])[0]  #=> 2

Hier ist ein einfaches Beispiel, das den Vorteil nutzt, dass das Delegations-Objekt von SimpleDelegator jederzeit geändert werden kann.

class Stats
  def initialize
    @source = SimpleDelegator.new([])
  end

  def stats(records)
    @source.__setobj__(records)

    "Elements:  #{@source.size}\n" +
    " Non-Nil:  #{@source.compact.size}\n" +
    "  Unique:  #{@source.uniq.size}\n"
  end
end

s = Stats.new
puts s.stats(%w{James Edward Gray II})
puts
puts s.stats([1, 2, 3, nil, 4, 5, 1, 2])

Ausgabe

Elements:  4
 Non-Nil:  4
  Unique:  4

Elements:  8
 Non-Nil:  7
  Unique:  6