From: Patrick Bennett Date: 2003-08-22T13:35:21+09:00 Subject: Re: Class variables - a surprising result Yukihiro Matsumoto wrote: >I fell sympathy for your confusion. Unfortunately I can't satisfy >everyone. I'm trying anyway. > Well, keep it up, you've done a great job so far. :) >I'd like to know if you are a designer, how would you design class >variables in Ruby? And how useful they are in daily usage? >I'm just curious. > Hard to say.... Unfortunately the languages I've used (some for too long of a time) tend to cloud my judgement a bit. I'd probably side more towards the c++ static equivalent where a 'class' variable (ie: static int x;) is basically a unique variable that's within the namespace of the class but that follows standard visibility rules during inheritance. If a derived class defines a static (as opposed to an 'instance' variable) then unless explicitly scoped (class::variable) that class's variable will be referenced. If a base class changes its static, only the base class (and in a way, any subclass that didn't define a variable with the same name) are affected. I guess the real issue is that in Ruby there's no way to explicitly 'declare' a variable. Assigning to it either creates it, or assigns to the existing instance, so there's no way for derived classes to declare *their own* version of a variable with the same name and be able to refer to their version or the base class version at will. Talking through it now, and seeing what what the real source of my confusion was, I don't think it's an issue. Ruby can't do something I can do in C++ (guys, please, I don't want to see a bunch of posts to simulate this), but honestly, it's not something you really want to do anyway. 'Hiding' base class variables is usually bad news. The source of my confusion was that when I saw @@x = y, I equated that to a static declaration (somewhere) and it being assigned an initial value, not just another assignment to a variable scoped by a class hierarchy (as if it was effectively declared in the base class). If it matters, this is is how I was seeing it all: class A @@val = 5 def print puts "A print - val:#{@@val}" @@val = 6 end end class B < A @@val = 8 def print super puts "B print - val:#{@@val}" end end foo = B.new foo.print ----- A print - val:8 B print - val:6 A print - val:6 B print - val:6 The equivalent code (at least in terms of how I was looking at it - thus the source of my confusion) in C++, C#, Delphi (and others) would print 5, 8, 6, 8