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

Reply via email to