# # A concrete implementation of Delegator, this class provides the means to # delegate all supported method calls to the object passed into the constructor # and even to change the object being delegated to at a later time with # #__setobj__. # # 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__ #=> # # # A SimpleDelegator instance can take advantage of the fact that SimpleDelegator # is a subclass of `Delegator` to call `super` to have methods called on the # object being delegated to. # # class SuperArray < SimpleDelegator # def [](*args) # super + 1 # end # end # # SuperArray.new([1])[0] #=> 2 # # Here's a simple example that takes advantage of the fact that # SimpleDelegator's delegation object can be changed at any time. # # 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]) # # Prints: # # Elements: 4 # Non-Nil: 4 # Unique: 4 # # Elements: 8 # Non-Nil: 7 # Unique: 6 # class SimpleDelegator < Delegator public # # Returns the current object method calls are being delegated to. # def __getobj__: () -> untyped # # Changes the delegate object to *obj*. # # It's important to note that this does **not** cause SimpleDelegator's methods # to change. Because of this, you probably only want to change delegation to # objects of the same type as the original delegate. # # Here's an example of changing the delegation object. # # names = SimpleDelegator.new(%w{James Edward Gray II}) # puts names[1] # => Edward # names.__setobj__(%w{Gavin Sinclair}) # puts names[1] # => Sinclair # def __setobj__: (untyped obj) -> untyped end