| 
 | |||
| Previous < | Contents ^ | Next > | |
each.
| Library: delegate | 
Delegator class implements a simple but powerful
delegation scheme, where requests are automatically forwarded from a
master class to delegates or their ancestors, and where the delegate
can be changed at runtime with a single method call.
The delegate.rb library provides two mechanisms for allowing an
object to forward messages to a delegate.
DelegateClass, passing the name of the class to be
  delegated as a parameter (Example 1). Then, in your class's
  initialize method, you'd call the superclass, passing in
  the object to be delegated.  For example, to declare a class
  Fred that also supports all the methods in Flintstone, you'd
  write
| class Fred < DelegateClass(Flintstone) def initialize # ... super(Flintstone.new(...)) end # ... end | 
SimpleDelegator (Example 2). You
   can also add delegation capabilities to an existing object using
   SimpleDelegator (Example 3). In these cases, you can call the
   __setobj__ method in SimpleDelegator to
   change the object being delegated at runtime.
DelegateClass method and subclass
  the result when you need a class with its own behavior that also
  delegates to an object of another class. In this example, we assume
  that the @sizeInInches array is large, so we want only one copy
  of it. We then define a class that accesses it, converting the
  values to feet.
| 
require 'delegate'
sizeInInches = [ 10, 15, 22, 120 ]
class Feet < DelegateClass(Array)
  def initialize(arr)
    super(arr)
  end
  def [](*n)
    val = super(*n)
    case val.type
    when Numeric; val/12.0
    else;         val.collect {|i| i/12.0}
    end
  end
end
 | 
| sizeInFeet = Feet.new(sizeInInches) | ||
| sizeInInches[0..3] | » | [10, 15, 22, 120] | 
| sizeInFeet[0..3] | » | [0.8333333333, 1.25, 1.833333333, 10.0] | 
SimpleDelegator when you want an
  object that both has its own behavior and delegates to
  different objects during its lifetime.  This is an example of the
  State
  pattern.  
  Objects of class TicketOffice sell tickets if a
  seller is available, or tell you to come back tomorrow if there is
  no seller.
| require 'delegate' class TicketSeller def sellTicket() return '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" | 
SimpleDelegator objects when you want
  a single object to delegate all its methods to two or more other
  objects.
| # Example 3 - delegate from existing object | ||
| seller   = TicketSeller.new | ||
| noseller = NoTicketSeller.new | ||
| to = SimpleDelegator.new(seller) | ||
| to.sellTicket | » | "Here's a ticket" | 
| to.sellTicket | » | "Here's a ticket" | 
| to.__setobj__(noseller) | ||
| to.sellTicket | » | "Sorry-come back tomorrow" | 
| to.__setobj__(seller) | ||
| to.sellTicket | » | "Here's a ticket" | 
| Library: observer | 
Observable module, which provides the methods for managing the
associated observer objects.
|  | ||||||||
| add_observer(obj) | Add obj as an observer on this object. obj will now receive notifications. | |||||||
| delete_observer(obj) | Delete obj as an observer on this object. It will no longer receive notifications. | |||||||
| delete_observers | Delete all observers associated with this object. | |||||||
| count_observers | Return the count of observers associated with this object. | |||||||
| changed(newState= true) | Set the changed state of this
  object. Notifications will be sent only if the changed state is true. | |||||||
| changed? | Query the changed state of this object. | |||||||
| notify_observers(*args) | If this object's changed state is
  true, invoke the updatemethod in each currently associated 
  observer in turn, passing it the given arguments. The changed state is then
  set tofalse. | |||||||
|  | ||||||||
update method to receive
notifications. 
| 
require "observer"
  class Ticker # Periodically fetch a stock price
    include Observable
    def initialize(symbol)
      @symbol = symbol
    end
    def run
      lastPrice = nil
      loop do
        price = Price.fetch(@symbol)
        print "Current price: #{price}\n"
        if price != lastPrice
          changed                 # notify observers
          lastPrice = price
          notify_observers(Time.now, price)
        end
      end
    end
  end
  class Warner
    def initialize(ticker, limit)
      @limit = limit
      ticker.add_observer(self)   # all warners are observers
    end
  end
  class WarnLow < Warner
    def update(time, price)       # callback for observer
      if price < @limit
        print "--- #{time.to_s}: Price below #@limit: #{price}\n"
      end
    end
  end
  class WarnHigh < Warner
    def update(time, price)       # callback for observer
      if price > @limit
        print "+++ #{time.to_s}: Price above #@limit: #{price}\n"
      end
    end
  end
ticker = Ticker.new("MSFT")
WarnLow.new(ticker, 80)
WarnHigh.new(ticker, 120)
ticker.run
 | 
| Current price: 83 Current price: 75 --- Sun Mar 04 23:26:31 CST 2001: Price below 80: 75 Current price: 90 Current price: 134 +++ Sun Mar 04 23:26:31 CST 2001: Price above 120: 134 Current price: 134 Current price: 112 Current price: 79 --- Sun Mar 04 23:26:31 CST 2001: Price below 80: 79 | 
| Library: singleton | 
singleton library makes this simple to implement. Mix
the Singleton module into each class that is to be a singleton,
and that class's new method will be made private. In its
place, users of the class call the method instance, which
returns a singleton instance of that class.
In this example, the two instances of MyClass are the same object.
| require 'singleton' | ||
|  | ||
| class MyClass | ||
|   include Singleton | ||
| end | ||
|  | ||
| a = MyClass.instance | » | #<MyClass:0x4018c924> | 
| b = MyClass.instance | » | #<MyClass:0x4018c924> | 
| Previous < | Contents ^ | Next > |