On Apr 29, 2007, at 8:44 PM, zswu wrote:

> 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