There's a brief article here http://www.oreillynet.com/ruby/blog/2006/01/ruby_design_patterns_observer.html
The procedure for setting up observers is quite different to KVO and I imagine it has different advantages/disadvantages to KVO, though I must admit I'm not particularly familiar with ruby observer pattern myself. On 29 Nov 2010, at 16:36, Matt Massicotte wrote: > I'm not familiar with the Ruby observer mechanism you refer to - could you > post a link? > > Matt > > On Nov 29, 2010, at 6:34 AM, Alan Skipp wrote: > >> I hope people don't mind me posting this bit of code to the list, but I hope >> it will be of some use to others and would also be interested to hear if the >> technique has any problems which I've not foreseen. >> >> Ruby has its own means of implementing the observer pattern, but as Key >> Value Observing (KVO) is so pervasive in cocoa, it would be good if it was >> easy to use. The module is an attempt at making KVO a bit more pleasant to >> use in macruby. >> The ideas have been adapted/stolen from here: >> >> https://gist.github.com/153676 >> >> The following is an example of how to have a block of code executed >> asynchronously every time a property of an instance variable changes >> >> self.add_observer_for_key_path('person.first_name', async:true) do >> |object,change| >> object.do_expensive_calculation #will not block main thread >> end >> >> A concern I do have is that the object which wants to receive KVO >> notifications holds an array of Observer objects. These Observer objects >> hold a reference to the object receiving the KVO notifications. Is this >> going to cause havoc with garbage collection? >> >> module KVO >> >> class Observer >> require 'dispatch' >> >> attr_reader :observee, :path >> def initialize(object, path, async, block, opts=0) >> @observee = object >> @path = path >> @async = async >> @block = block >> @observee.addObserver(self, forKeyPath:path, options:opts, context:nil) >> end >> >> def observeValueForKeyPath(path, ofObject:object, change:change, >> context:context) >> if @async >> Dispatch::Job.new { @block.call(object, change) } >> else >> @block.call(object, change) >> end >> end >> >> def cancel_observation >> @observee.removeObserver(self, forKeyPath:@path) >> end >> end >> >> def add_observer_for_key_path(path, async:async, &block) >> (@_observers_array_ ||= []) << Observer.new(self, path, async, block) >> end >> >> def add_observer_for_key_path(path, async:async, options:opts, &block) >> (@_observers_array_ ||= []) << Observer.new(self, path, async, block, >> opts) >> end >> >> def remove_observer_for_key_path(path) >> observer = @_observers_array_.find {|o| o.path == path && o.observee == >> self} if @_observers_array_ >> @_observers_array_.delete(observer) and observer.cancel_observation if >> observer >> end >> >> end >> _______________________________________________ >> MacRuby-devel mailing list >> MacRuby-devel@lists.macosforge.org >> http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel > > _______________________________________________ > MacRuby-devel mailing list > MacRuby-devel@lists.macosforge.org > http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
_______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel