From: "David A. Black" Date: 2005-07-12T07:27:42+09:00 Subject: Re: class_attr_accessor Hi -- On Tue, 12 Jul 2005, Jeffrey Moss wrote: > I was playing around with class variables and class instance variables > because I wanted to implement a certain functionality, while not really > understanding the coexistence of the two, I found the reason the two exist is > quite clear, the class instance variables facilitate "subclass slots" (as I > know them from other languages) while the @@ syntax facilitates "class slots" I'm not sure what you mean (but I'm not familiar with the term "subclass slot"). If a class object has instance variables, there are no implications for the subclasses: class A @x = 1 end class B < A p instance_variables # [] end This is really just because instance variables are per-object, so the instance variables belonging to the object A are of no concern to any other object (including B). But, again, I'm not sure I'm getting what you meant about subclasses. > I did a google search for "class_attr_accessor" and found that a number of > people have implemented this functionality in their own code. I suggest it > be officially added to the ruby distribution. > > Here is an example: > > class Module > private > def class_attr_accessor(*attrs) > attrs.each {|attr| > module_eval(<<-EOS) > class << self > def #{attr}; @#{attr}; end > def #{attr}=(v); @#{attr} = v; end > end > EOS > } > end > end > > I really don't think a new notation, similar to @@, is necessary, I think > calling obj.class.accessor_name is very nice. In fact having both a > subclass_attr_accessor and a class_attr_accessor wouldn't hurt either. In > that case, class_attr_accessor would just be a way to make @@vars public. I'm still not sure where subclasses come in; they're different objects, so they have different instance variables. Also, class variables (@@var) aren't part of the whole attr_* and instance variable universe, so I don't think you'd want to have a method with an attr_* name that dealt in class variables. It would just get confusing. Actually I would say not only is a new notation not necessary for class instance variables, but a new method isn't either :-) What we sometimes call "class instance variables" are not a separate language-level construct. They are simply instance variables which happen to belong to a Class object. The object (like any other object) can choose to expose them, keep state in them, etc. Consider these two examples: class C class << self attr_accessor :x end end some_string = "I am a string" class << some_string attr_accessor :y end In both cases, I've created an accessor for an object. One is a Class object (C); one is a String object (some_string). But I don't expect there to be a class_attr_accessor or string_attr_accessor method. I just get myself into the right scope (with the class keyword), and then I call attr_accessor. Classes are not special cases in this context. In both cases, too, the accessors will be implemented using instance variables (since that's how attr_* works). The fact that C is a Class object does not change this, one way or the other: there's no involvement of different variables (such as @@var), and there's no *more* involvement of other objects (such as instances or subclasses of C) than there is in cases where the object gettings accessorized is not a Class. I think it can be useful to use the term "class instance variable" in cases where someone might mistakenly think that you're talking about an instance variable of instances of a class, and you want to clarify that that's not what you mean. But it's actually not a separate construct, and attr_* works the same for Class objects as for other objects. I would personally be opposed to introducing the appearance of a difference into the language. David -- David A. Black dblack@wobblini.net