From: Simon Conrad-Armes (Curne) Date: 2005-01-11T21:42:03+09:00 Subject: Re: Inheritance of class variables Hi all, Personally I never use class variables, since I consider them inherently broken. Although I have no constructive opinion of how they _should_ function, I know after trying several times, that they simply do not work the way I want to use them. Instead I sometimes use class _instance_ variables, that is instance variables on the class object. The idea is exactly the same as Guy's, but with lazy initialization, so I get to skip some of the instance_evals. Thus my version of the code would look like... ------------------------------------------------------------------------ class CarBuilder def initialize(name) @name = name end def self.total_of_cars @total_of_cars or 0 end def self.increase_total @total_of_cars = (@total_of_cars or 0) + 1 end def build puts "#{@name} building another car ..." self.class.increase_total end def total_of_cars "#{@name} built #{self.class.total_of_cars} cars" end end class Honda < CarBuilder def initialize super("Honda") end end class Ford < CarBuilder def initialize super("Ford") end end h = Honda.new f = Ford.new puts h.total_of_cars puts f.total_of_cars h.build h.build h.build f.build puts h.total_of_cars puts f.total_of_cars ------------------------------------------------------------------------ The output then shows 3 Hondas and 1 Ford. Of course, this is a simple special case of a factory object, the class object being the factory. Thus I would probably write the code slightly different, putting the #total_of_cars method on the class and making #build a synonym of #new, which would seem to me the saner approach. Just my two euro-cents. /Curne -- Mailing lists confuse me. Often I don't recognize my own posts and set about writing a flaming reply where I violently disagree. [curne@curnomatic.dk] On 2004 Dec, 30, at 14:17, Eustaquio Rangel de Oliveira Jr. wrote: > Hello there. > > I was talking with chris2 and matju on the irc channel and they gave > me good explanation about this point, but I'd like to share it with > you and discuss something about it. > > I was asking about if, when defined on a parent class, a class > variable overwrites the class variables with the same name on it's > children. > > For example: > > ----------------------------------------------------------------------- > - > class CarBuilder > @@total_of_cars=0 > def initialize(name) > @name = name > end > def build > puts "#{@name} building another car ..." > @@total_of_cars +=1 > end > def total_of_cars > "#{@name} built #{@@total_of_cars} cars" > end > end > > class Honda < CarBuilder > @@total_of_cars=0 > def initialize > super("Honda") > end > end > > class Ford < CarBuilder > @@total_of_cars=0 > def initialize > super("Ford") > end > end > > h = Honda::new > f = Ford::new > > puts h.total_of_cars > puts f.total_of_cars > > h.build > h.build > h.build > f.build > > puts h.total_of_cars > puts f.total_of_cars > ----------------------------------------------------------------------- > - > > Running this code we have: > > ----------------------------------------------------------------------- > - > Honda built 0 cars > Ford built 0 cars > Honda building another car ... > Honda building another car ... > Honda building another car ... > Ford building another car ... > Honda built 4 cars > Ford built 4 cars > ----------------------------------------------------------------------- > - > > So, there is a mistake here. Honda built 3 cars and Ford 1, and not 4 > for Honda and 4 for Ford. They are sharing the parent class variable, > not matter if it was defined on the children also. > > Matsu told me that who came first is the boss, so if @@total_of_cars > was defined on the parent, not matter what, all the other children > will refer to it. I can live with that making some hacks ehehe but let > me see: > > ----------------------------------------------------------------------- > - > class CarBuilder > def initialize(name) > @name = name > end > def build > puts "#{@name} building another car ..." > increase > end > def increase > end > end > > class Honda < CarBuilder > @@total_of_cars=0 > def initialize > super("Honda") > end > def increase > @@total_of_cars +=1 > end > def total_of_cars > "#{@name} built #{@@total_of_cars} cars" > end > end > > class Ford < CarBuilder > @@total_of_cars=0 > def initialize > super("Ford") > end > def increase > @@total_of_cars +=1 > end > def total_of_cars > "#{@name} built #{@@total_of_cars} cars" > end > end > > h = Honda::new > f = Ford::new > > puts h.total_of_cars > puts f.total_of_cars > > h.build > h.build > h.build > f.build > > puts h.total_of_cars > puts f.total_of_cars > ----------------------------------------------------------------------- > - > > Running it I got: > > ----------------------------------------------------------------------- > - > Honda built 0 cars > Ford built 0 cars > Honda building another car ... > Honda building another car ... > Honda building another car ... > Ford building another car ... > Honda built 3 cars > Ford built 1 cars > ----------------------------------------------------------------------- > - > > That is the correct behaviour. > But let check what I changed there on the code: > > - I removed @@total_of_cars from CarBuilder, and put it on *each* > child class (there was one row of code, now there is two - or more, if > more children), and could be a problem if I miss the point on some > child class and forget to declare that variable there). > > - On the CarBuilder, I create an empty method there called "increase" > just to call it on the "build" method (that I want the children > inherit it's funcionality). Two more rows there. > > - I also removed the total_of_cars method from CarBuilder, but needed > to write it on each children. 3 rows less on the parent, but 3 more on > each child. > > - Also on the children I needed to write the increase method, 3 more > rows on each child. > > Sorry if I'm missing some point here, because I'm a Ruby newbie, but > is that correct? I mean, seems that we need to write more code with > this kind of behaviour. > > And if we forget to implement some of the needed methods or the > @@total_of_cars on each CarBuilder child (CarBuilder could have a lot > of other methods that I could want to inherit also!), it could not > work normally. > > On another point, if all this methods and variables could be inherited > from the parent class, will be no problem. > > I don't really know if there is a strong and well-defined OOP concept > on the fact that a child cannot overwrite it's parent class variables, > but could you > > - Tell me if there is some kind of OOP concept like that and > - Tell me if the way I made the code, even with more lines, is the > correct and more efficient way to control how many cars each > CarBuilder child made? > > Thanks for your attention. :-) > > ---------------------------- > Eust�quio "TaQ" Rangel > eustaquiorangel@yahoo.com > http://beam.to/taq > Usu�rio GNU/Linux no. 224050 > > >