From: Joel VanderWerf Date: 2004-11-11T06:03:15+09:00 Subject: Re: automatically call function on attribute set Joe Laughlin wrote: > I have a class that represents an airplane. This class has a bunch of data > members: x/y/z positions, x/y/z velocities, pitches, rolls, etc. What I did > is let the user configure what different attributes the airplane had in a > YAML config file, then have the airplane class read in that file and setup > attr_accessors for each attribute in the file. > > I have another object (call it airplane_drawing) that is responsible for > drawing this airplane on the screen. It needs to have access to some of the > attributes of the airplane, and it needs have some of its own attributes > changed whenever airplane's attributes changes. > > What is the best way to get airplane_drawing to be notified whenever some > attribute of airplane is changed? Should I have a thread (or similar) that > checks the airplane object to see if anything's changed? > > I hope I've explained this well enough for people to understand... I feel > like this is a fairly common thing to do, but I'm not sure of the best way > to do it. Another approach is the observable lib on RAA (http://raa.ruby-lang.org/list.rhtml?name=observable). require 'observable' class Airplane extend Observable observable :x, :y, :z def initialize(x = 0, y = 0, z = 0) @x, @y, @z = x, y, z end def fly self.x += 1 # don't use @x=, or else no notification end end class Drawing def initialize(airplane) airplane.when_x do puts "moving in x dimension to #{airplane.x}" end end end airplane = Airplane.new drawing = Drawing.new(airplane) # ==> moving in x dimension to 0 airplane.fly # ==> moving in x dimension to 1 airplane.fly # ==> moving in x dimension to 2 The observer.rb in the standard library is better if you want more control over sending the notification. For example, if x,y,z all change, but you only want to send the notification once for all three. (Or you could use an attribute that contains the whole x,y,z point, and make that observable.)