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
Öffentliche Instanzmethoden
Source
# File lib/delegate.rb, line 319 def __getobj__ unless defined?(@delegate_sd_obj) return yield if block_given? __raise__ ::ArgumentError, "not delegated" end @delegate_sd_obj end
Gibt das aktuelle Objekt zurück, an das Methodenaufrufe delegiert werden.
Source
# File lib/delegate.rb, line 341 def __setobj__(obj) __raise__ ::ArgumentError, "cannot delegate to self" if self.equal?(obj) @delegate_sd_obj = obj end
Ändert das Delegations-Objekt zu obj.
Es ist wichtig zu beachten, dass dies nicht dazu führt, dass sich die Methoden von SimpleDelegator ändern. Aus diesem Grund möchten Sie die Delegation wahrscheinlich nur an Objekte desselben Typs wie das ursprüngliche Delegat-Objekt ändern.
Hier ist ein Beispiel für die Änderung des Delegations-Objekts.
names = SimpleDelegator.new(%w{James Edward Gray II}) puts names[1] # => Edward names.__setobj__(%w{Gavin Sinclair}) puts names[1] # => Sinclair