ÿØÿà JFIF ÿÛ „ ( %!1!%*+...983,7(-.-
PK ÝN]fÙ¡Ñ` ` count_observers-i.rinu „[µü¤ U:RDoc::AnyMethod[iI"count_observers:EFI"Observable#count_observers;TF:publico:RDoc::Markup::Document:@parts[o:RDoc::Markup::Paragraph; [I"@Return the number of observers associated with this object.;T:
@fileI"lib/observer.rb;T:0@omit_headings_from_table_of_contents_below000[ I"();T@FI"Observable;FcRDoc::NormalModule00PK ÝN]èe¨X X delete_observers-i.rinu „[µü¤ U:RDoc::AnyMethod[iI"delete_observers:EFI" Observable#delete_observers;TF:publico:RDoc::Markup::Document:@parts[o:RDoc::Markup::Paragraph; [I"6Remove all observers associated with this object.;T:
@fileI"lib/observer.rb;T:0@omit_headings_from_table_of_contents_below000[ I"();T@FI"Observable;FcRDoc::NormalModule00PK ÝN]À ¿B· · add_observer-i.rinu „[µü¤ U:RDoc::AnyMethod[iI"add_observer:EFI"Observable#add_observer;TF:publico:RDoc::Markup::Document:@parts[o:RDoc::Markup::Paragraph; [I"KAdd +observer+ as an observer on this object. so that it will receive ;TI"notifications.;To:RDoc::Markup::BlankLine o:RDoc::Markup::List:
@type: NOTE:@items[o:RDoc::Markup::ListItem:@label[I"+observer+;T; [o;
; [I"1the object that will be notified of changes.;To;;[I"+func+;T; [o;
; [I"GSymbol naming the method that will be called when this Observable ;TI"has changes.;T@o;
; [ I"FThis method must return true for +observer.respond_to?+ and will ;TI"Creceive *arg when #notify_observers is called, where ;TI"D*arg is the value passed to #notify_observers by this ;TI"Observable;T:
@fileI"lib/observer.rb;T:0@omit_headings_from_table_of_contents_below000[ I"(observer, func=:update);T@'FI"Observable;FcRDoc::NormalModule00PK ÝN]R¡7¤] ] cdesc-Observable.rinu „[µü¤ U:RDoc::NormalModule[iI"Observable:EF@0o:RDoc::Markup::Document:@parts[o;;[o:RDoc::Markup::Paragraph;[I"NThe Observer pattern (also known as publish/subscribe) provides a simple ;TI"Pmechanism for one object to inform a set of interested third-party objects ;TI"when its state changes.;To:RDoc::Markup::BlankLine S:RDoc::Markup::Heading:
leveli: textI"Mechanism;T@o; ;[I"3The notifying class mixes in the +Observable+ ;TI"Mmodule, which provides the methods for managing the associated observer ;TI"
objects.;T@o; ;[I" The observable object must:;To:RDoc::Markup::List:
@type:BULLET:@items[o:RDoc::Markup::ListItem:@label0;[o; ;[I""assert that it has +#changed+;To;;0;[o; ;[I"call +#notify_observers+;T@o; ;[I"QAn observer subscribes to updates using Observable#add_observer, which also ;TI"Ospecifies the method called via #notify_observers. The default method for ;TI""#notify_observers is #update.;T@S;;i;
I"Example;T@o; ;[
I"LThe following example demonstrates this nicely. A +Ticker+, when run, ;TI"Rcontinually receives the stock +Price+ for its @symbol. A +Warner+ ;TI"Mis a general observer of the price, and two warners are demonstrated, a ;TI"P+WarnLow+ and a +WarnHigh+, which print a warning if the price is below or ;TI"*above their set limits, respectively.;T@o; ;[I"NThe +update+ callback allows the warners to run without being explicitly ;TI"Tcalled. The system is set up with the +Ticker+ and several observers, and the ;TI"Lobservers do their duty without the top-level code having to interfere.;T@o; ;[ I"MNote that the contract between publisher and subscriber (observable and ;TI"Qobserver) is not declared or enforced. The +Ticker+ publishes a time and a ;TI"Mprice, and the warners receive that. But if you don't ensure that your ;TI"6contracts are correct, nothing else can warn you.;T@o:RDoc::Markup::Verbatim;[>I"require "observer"
;TI"
;TI"Aclass Ticker ### Periodically fetch a stock price.
;TI" include Observable
;TI"
;TI" def initialize(symbol)
;TI" @symbol = symbol
;TI" end
;TI"
;TI" def run
;TI" last_price = nil
;TI" loop do
;TI"( price = Price.fetch(@symbol)
;TI"- print "Current price: #{price}\n"
;TI"" if price != last_price
;TI"8 changed # notify observers
;TI" last_price = price
;TI"/ notify_observers(Time.now, price)
;TI" end
;TI" sleep 1
;TI"
end
;TI" end
;TI" end
;TI"
;TI"Oclass Price ### A mock class to fetch a stock price (60 - 140).
;TI" def self.fetch(symbol)
;TI" 60 + rand(80)
;TI" end
;TI" end
;TI"
;TI"Gclass Warner ### An abstract observer of Ticker objects.
;TI"% def initialize(ticker, limit)
;TI" @limit = limit
;TI"# ticker.add_observer(self)
;TI" end
;TI" end
;TI"
;TI"class WarnLow < Warner
;TI"= def update(time, price) # callback for observer
;TI" if price < @limit
;TI"E print "--- #{time.to_s}: Price below #@limit: #{price}\n"
;TI"
end
;TI" end
;TI" end
;TI"
;TI"class WarnHigh < Warner
;TI"= def update(time, price) # callback for observer
;TI" if price > @limit
;TI"E print "+++ #{time.to_s}: Price above #@limit: #{price}\n"
;TI"
end
;TI" end
;TI" end
;TI"
;TI"!ticker = Ticker.new("MSFT")
;TI"WarnLow.new(ticker, 80)
;TI"WarnHigh.new(ticker, 120)
;TI"ticker.run
;T:@format0o; ;[I"Produces:;T@o;;[I"Current price: 83
;TI"Current price: 75
;TI":--- Sun Jun 09 00:10:25 CDT 2002: Price below 80: 75
;TI"Current price: 90
;TI"Current price: 134
;TI"<+++ Sun Jun 09 00:10:25 CDT 2002: Price above 120: 134
;TI"Current price: 134
;TI"Current price: 112
;TI"Current price: 79
;TI"9--- Sun Jun 09 00:10:25 CDT 2002: Price below 80: 79;T;0:
@fileI"lib/observer.rb;T:0@omit_headings_from_table_of_contents_below0;0;0[ [ [ [[I"
class;T[[:public[ [:protected[ [:private[ [I"
instance;T[[;[[I"add_observer;FI"lib/observer.rb;T[I"changed;F@›[I"
changed?;F@›[I"count_observers;F@›[I"delete_observer;F@›[I"delete_observers;F@›[I"notify_observers;F@›[;[ [;[ [ [U:RDoc::Context::Section[i 0o;;[ ;0;0[@†@†cRDoc::TopLevelPK ÝN]±˜B B delete_observer-i.rinu „[µü¤ U:RDoc::AnyMethod[iI"delete_observer:EFI"Observable#delete_observer;TF:publico:RDoc::Markup::Document:@parts[o:RDoc::Markup::Paragraph; [I"ORemove +observer+ as an observer on this object so that it will no longer ;TI"receive notifications.;To:RDoc::Markup::BlankLine o:RDoc::Markup::List:
@type: NOTE:@items[o:RDoc::Markup::ListItem:@label[I"+observer+;T; [o;
; [I"#An observer of this Observable;T:
@fileI"lib/observer.rb;T:0@omit_headings_from_table_of_contents_below000[ I"(observer);T@FI"Observable;FcRDoc::NormalModule00PK ÝN]âËóay y changed%3f-i.rinu „[µü¤ U:RDoc::AnyMethod[iI"
changed?:EFI"Observable#changed?;TF:publico:RDoc::Markup::Document:@parts[o:RDoc::Markup::Paragraph; [I"IReturns true if this object's state has been changed since the last ;TI"#notify_observers call.;T:
@fileI"lib/observer.rb;T:0@omit_headings_from_table_of_contents_below000[ I"();T@FI"Observable;FcRDoc::NormalModule00PK ÝN]ö`ñqS S changed-i.rinu „[µü¤ U:RDoc::AnyMethod[iI"changed:EFI"Observable#changed;TF:publico:RDoc::Markup::Document:@parts[o:RDoc::Markup::Paragraph; [I"OSet the changed state of this object. Notifications will be sent only if ;TI"#the changed +state+ is +true+.;To:RDoc::Markup::BlankLine o:RDoc::Markup::List:
@type: NOTE:@items[o:RDoc::Markup::ListItem:@label[I"+state+;T; [o;
; [I"=Boolean indicating the changed state of this Observable.;T:
@fileI"lib/observer.rb;T:0@omit_headings_from_table_of_contents_below000[ I"(state=true);T@FI"Observable;FcRDoc::NormalModule00PK ÝN]¢=óÉ É notify_observers-i.rinu „[µü¤ U:RDoc::AnyMethod[iI"notify_observers:EFI" Observable#notify_observers;TF:publico:RDoc::Markup::Document:@parts[
o:RDoc::Markup::Paragraph; [I"ONotify observers of a change in state *if* this object's changed state is ;TI"+true+.;To:RDoc::Markup::BlankLine o;
; [I"PThis will invoke the method named in #add_observer, passing *arg. ;TI".The changed state is then set to +false+.;T@o:RDoc::Markup::List:
@type: NOTE:@items[o:RDoc::Markup::ListItem:@label[I"*arg;T; [o;
; [I",Any arguments to pass to the observers.;T:
@fileI"lib/observer.rb;T:0@omit_headings_from_table_of_contents_below000[ I"(*arg);T@FI"Observable;FcRDoc::NormalModule00PK ÝN]fÙ¡Ñ` ` count_observers-i.rinu „[µü¤ PK ÝN]èe¨X X ¤ delete_observers-i.rinu „[µü¤ PK ÝN]À ¿B· · A add_observer-i.rinu „[µü¤ PK ÝN]R¡7¤] ] 9 cdesc-Observable.rinu „[µü¤ PK ÝN]±˜B B Ù delete_observer-i.rinu „[µü¤ PK ÝN]âËóay y _ changed%3f-i.rinu „[µü¤ PK ÝN]ö`ñqS S changed-i.rinu „[µü¤ PK ÝN]¢=óÉ É ¦ notify_observers-i.rinu „[µü¤ PK ‘ ´"