If you know C++.
@foo seams look link a normal member variable , i.e. private TYPE foo
@@foo seams look link a static member variable, i.e. static TYPE foo
I think a lot of confusion about Ruby class variables comes from
trying to compare them to similarly named constructs in other languages.
There is also a tendency to think class variables are like instance
variables because @@ is like @. Again, you'll be mislead by that
assumption.
1) Class variables are lexically scoped. They are *not* associated
with the object identified by 'self' but instead by the innermost
class block:
class B;end
class A
@@foo = 42 # @@foo for A
def foo
@@foo # @@foo for A
end
def B.foo
@@foo # self is B but @@foo is for A
end
end
puts A.new.foo # 42
puts B.foo # 42
This lexical scoping is really important to understand when you
start using singleton class blocks, class_eval, module_eval,
or define_method, since the these constructs don't introduce a lexical
scope:
class X
@@foo = 42
class Y
@@foo = 43
X.class_eval {
puts @@foo # 43, this is Y's @@foo, not X's @@foo
}
end
end
2) Class variables are associated with a class *and* its subclasses
and the order of initialization is important.
class C
@@foo = 42 # shared by C and its decendents!
def foo
@@foo # shared with C, D, and E
end
def bar
@@bar # this is C's @@bar
end
end
class D < C
end
class E < C
@@foo = 43 # @@foo shared with C, D, and E
@@bar = 44 # @@bar only defined for E
def bar
@@bar # this is E's @@bar
end
end
puts D.new.foo # 43
puts E.new.bar # 44
puts C.new.bar # undefined!
class C
@@bar = 45
end
puts C.new.bar # 45
puts E.new.bar # still 44
Initialize the class variable in the constroctor is a good idea.
That's will make the class variable valide all of the class.
class xxx
def initialize
@@foo = XXXXX
end
end
This is a really bad idea. Every time you create a new instance,
you'll reset the class variable.
Gary Wright
···
On Apr 29, 2007, at 8:44 PM, zswu wrote: