From: "Dan Stevens (IAmAI)" Date: 2007-07-06T16:10:00+09:00 Subject: Re: Calling an arbitrary method as and when an array's contents change I contemplated using the #hash method to determine if the array had changed: [snip] def method_missing(meth, *args, &block) @last_hash = @array.hash @array.send(meth, *args, &block) if @array.hash != @last_hash changed notify_observers(@array, meth, *args, &block) end end [snip] That way I don't have to worry about which methods change the contents of the array. On 06/07/07, James Edward Gray II wrote: > On Jul 5, 2007, at 6:04 PM, Dan Stevens (IAmAI) wrote: > > >> For this purpose, it's probably better to wrap/delegate to Array > >> than extend it. > > > > This is a potential solution - I could override all the methods of the > > Array class that I think modify the contents of the Array in a > > superclass, calling Observable#changed before/after calling the > > parent's method. However, what if I think there's one too many methods > > to be overriding or a forget to override one? > > It's really not too much work: > > #!/usr/bin/env ruby -wKU > > require "observer" > > class OArray > instance_methods.each { |meth| undef_method(meth) unless meth =~ / > \A__/ } > > include Observable > > def initialize(array) > @array = array > end > > def method_missing(meth, *args, &block) > @array.send(meth, *args, &block) > > if %w{ []= clear concat delete delete_at > delete_if fill pop push replace shift }.include? > (meth.to_s) or > meth.to_s[-1] == ?! > changed > notify_observers(@array, meth, *args, &block) > end > end > end > > class Array > def to_oarray > OArray.new(self) > end > end > > observer = Object.new > class << observer > def update(array, *call) > puts "You called #{call.first} and the Array is now # > {array.inspect}." > end > end > > observed = [1, 2, 3].to_oarray > observed.add_observer(observer) > observed[1] > observed[1] = "2" > > __END__ > > James Edward Gray II > >