From: David Flanagan Date: 2007-09-21T02:49:49+09:00 Subject: Re: class variables and singleton classes Eric, I think this is just one manifestation of the fact that class variables are no longer shared between classes and subclasses. That is: I don't think the behavior you're seeing is specific to singletons. Here's what I write about class variables and inheritance in the book I'm working on. These particular paragraphs have not been through technical review, but I think I've got it right. (Also note that the info on eigenclass.org about class variables is out-of-date and the code snippets there no longer do what they are said to do: --- begin book excerpt --- Class variables are inherited by subclasses. If a class A defines a variables @@a, then a subclass B can use that variable. In Ruby 1.9 and later, class variables behave like constants. That is, when a subclass assigns a new value to a class variable defined by a superclass, it is simply creating a new class variable in the subclass, and it does not affect the superclass's copy of the variable. In Ruby 1.8 and earlier, however, class variables are actually shared between classes and their subclasses. If a subclass assigns a value to a class variable already in use by a superclass, it alters the value seen by the superclass. The mere presence of the subclass can alter the behavior of any class methods in the superclass that use the class variable. This is a strong argument for the use of class instance variables instead of class variables. The following code illustrates the differences between versions of Ruby. It outputs "123" in Ruby 1.8 and outputs "111" in Ruby 1.9: --- end book excerpt -- David Eric Hodel wrote: > Class variables in singleton classes are separate from class variables > in classes in 1.9 now. Is this on purpose? > > $ cat class_variables.rb > module X > @@cv1 = nil > > class << self > def cv1() @@cv1 ||= 'cv1' end > end > > def self.cv1=(obj) @@cv1 = obj end > > @@cv2 = nil > > def self.cv2() @@cv2 ||= 'cv2' end > def self.cv2=(obj) @@cv2 = obj end > end > > p X.cv1 > X.cv1 = 'new1' > p X.cv1 > > p X.cv2 > X.cv2 = 'new2' > p X.cv2 > > $ ruby18 -v class_variables.rb > ruby 1.8.6 (2007-06-30 patchlevel 5000) [i686-darwin8.10.1] > "cv1" > "new1" > "cv2" > "new2" > $ ruby19 -v class_variables.rb > ruby 1.9.0 (2007-09-15 patchlevel 0) [i686-darwin8.10.1] > syck.so: warning: method redefined; discarding old value > "cv1" > "cv1" > "cv2" > "new2" > > -- > Poor workers blame their tools. Good workers build better tools. The > best workers get their tools to do the work for them. -- Syndicate Wars > > >