# Mixins and class variables

**URL:** <https://www.ruby-forum.com/t/mixins-and-class-variables/123327>\
**Category:** Ruby\
**Created:** [December 16, 2007, 4:26pm UTC](https://www.ruby-forum.com/t/mixins-and-class-variables/123327 "2007-12-16T16:26:21Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Brubix](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/f19dbf/32.png) [@Brubix](https://www.ruby-forum.com/u/Brubix)\
**Post date:** [December 16, 2007, 4:26pm UTC](https://www.ruby-forum.com/t/mixins-and-class-variables/123327/1 "2007-12-16T16:26:21Z")

</div>

I can’t figure out how to set class variables from class methods  
inherited from a module ?

The following doesn’t work as I expected (I spare you my others  
pathetic attempts):

module MyModule  
def self.extended(base)  
base.setClassVar(base.name.downcase)  
end  
def setClassVar(value)  
puts “self is #{self.name}”  
puts “@@classVar=#{value}”  
@@classVar = value  
end  
def getClassVar  
@@classVar  
end  
end

class Class1  
extend MyModule  
end  
class Class2  
extend MyModule  
end

puts "classVar for Class1 is " + Class1.getClassVar  
puts "classVar for Class2 is " + Class2.getClassVar

It gives:  
self is Class1  
@@classVar=class1  
self is Class2  
@@classVar=class2  
classVar for Class1 is class2 # Shouldn’t be class1 ?!  
classVar for Class2 is class2

Many thanks in advance.

Brubix

---

<div class="post-metadata">

**Author:** ![Brubix](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/f19dbf/32.png) [@Brubix](https://www.ruby-forum.com/u/Brubix)\
**Post date:** [December 16, 2007, 5:59pm UTC](https://www.ruby-forum.com/t/mixins-and-class-variables/123327/2 "2007-12-16T17:59:04Z")

</div>

On Dec 16, 9:25 am, Brubix [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> ```
> def setClassVar(value)
> extend MyModule
> 
> ```
> 
> @@classVar=class1  
> self is Class2  
> @@classVar=class2  
> classVar for Class1 is class2 # Shouldn’t be class1 ?!  
> classVar for Class2 is class2
> 
> Many thanks in advance.
> 
> Brubix

Use Module#class\_variable\_get/set for this kind of thing.

module MyModule  
def self.extended(base)  
base.setClassVar(base.name.downcase)  
end  
def setClassVar(value)  
puts “self is #{self.name}”  
puts “@@classVar=#{value}”  
class\_variable\_set(:@@classVar, value)  
end  
def getClassVar  
class\_variable\_get(:@@classVar)  
end  
end

HTH,  
Jordan

---

<div class="post-metadata">

**Author:** ![Brubix](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/f19dbf/32.png) [@Brubix](https://www.ruby-forum.com/u/Brubix)\
**Post date:** [December 16, 2007, 6:49pm UTC](https://www.ruby-forum.com/t/mixins-and-class-variables/123327/3 "2007-12-16T18:49:30Z")

</div>

On Dec 16, 9:33 am, Brubix [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > HTH,
> 
> Indeed !
> 
> No trace of them in my copy of the Pickaxe, so I feel my ignorance  
> partially excused.
> 
> Thanks.

Yeah, the pickaxe is only really a jumping off point. It definitely  
is slim on some of the more advanced topics, such as the full power of  
mixins and dynamic code.

---

<div class="post-metadata">

**Author:** ![Brubix](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/f19dbf/32.png) [@Brubix](https://www.ruby-forum.com/u/Brubix)\
**Post date:** [December 16, 2007, 6:34pm UTC](https://www.ruby-forum.com/t/mixins-and-class-variables/123327/4 "2007-12-16T18:34:49Z")

</div>

> HTH,

Indeed !

No trace of them in my copy of the Pickaxe, so I feel my ignorance  
partially excused.

Thanks.

---

<div class="post-metadata">

**Author:** ![Brubix](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/f19dbf/32.png) [@Brubix](https://www.ruby-forum.com/u/Brubix)\
**Post date:** [December 16, 2007, 9:08pm UTC](https://www.ruby-forum.com/t/mixins-and-class-variables/123327/5 "2007-12-16T21:08:34Z")

</div>

On Dec 16, 2007, at 10:25 AM, Brubix wrote:

> def setClassVar(value)  
> extend MyModule  
> @@classVar=class1  
> self is Class2  
> @@classVar=class2  
> classVar for Class1 is class2 # Shouldn’t be class1 ?!  
> classVar for Class2 is class2

The New Haven Ruby Brigade spent an hour or so one night trying  
to figure out the scoping rules for class variables.

The key to understanding them is to realize that instance variables  
are dynamical scoped relative to self while class variables  
are _lexically_ scoped (i.e. the scoping is defined by the  
syntactic structure of the code).

In your example, ‘@@classvar’ is lexically located within MyModule.  
That means it will _always_ be associated with MyModule regardless  
of the value of self at the time setClassVar or getClassVar are  
executed.

Here is another situation that illustrates this difference:

class A  
@@cvar = ‘class A’  
def cvar  
@@cvar  
end  
end

puts A.new.cvar # =\> class A  
puts A.class\_eval { @@cvar } # =\> NameError, @@cvar undefined

The class\_eval version fails because @@cvar in the block is  
not lexically within the class A/end block. It is _dynamically_  
in the scope of class A, but not lexically within the scope of  
class A. In this case, @@cvar is resolved to the top-level  
scope which is associated with Object.

MonkeeSage’s suggestion to use Module#class\_variable\_get/set  
forces the variables to be resolved relative to the receiver  
and thus bypasses the lexical scoping rules for class variables.

This is another situation where the syntactic similarity of the  
instance variable sigil ("@") and the class variable sigil ("@@")  
causes people to think they behave in the same manner. They don’t.

Gary W.

---

<div class="post-metadata">

**Author:** ![Brubix](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/f19dbf/32.png) [@Brubix](https://www.ruby-forum.com/u/Brubix)\
**Post date:** [December 16, 2007, 10:01pm UTC](https://www.ruby-forum.com/t/mixins-and-class-variables/123327/6 "2007-12-16T22:01:18Z")

</div>

On Dec 16, 2:07 pm, Gary W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > module MyModule  
> > end  
> > puts "classVar for Class2 is " + Class2.getClassVar  
> > to figure out the scoping rules for class variables.
> 
> puts A.class\_eval { @@cvar } # =\> NameError, @@cvar undefined
> 
> This is another situation where the syntactic similarity of the  
> instance variable sigil (“@”) and the class variable sigil (“@@”)  
> causes people to think they behave in the same manner. They don’t.
> 
> Gary W.

From the standpoint of intuitiveness, one would also expect that  
whatever scoping rules class variables follow, the same would be true  
of class methods; but that isn’t right either. Of course, class  
methods _have to_ be dynamically scoped or you couldn’t actually call  
them (doh!)…but it’s still strange to have class methods and class  
variables follow different scoping rules.

Regards,  
Jordan

---

<div class="post-metadata">

**Author:** ![Brubix](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/f19dbf/32.png) [@Brubix](https://www.ruby-forum.com/u/Brubix)\
**Post date:** [December 16, 2007, 9:15pm UTC](https://www.ruby-forum.com/t/mixins-and-class-variables/123327/7 "2007-12-16T21:15:00Z")

</div>

On Sunday 16 December 2007, Brubix wrote:

> I can’t figure out how to set class variables from class methods  
> inherited from a module ?

Consider if class variables are really what you want.

$ irb

> > module M  
> > def set(x)  
> > @x = x  
> > end  
> > def get  
> > @x  
> > end  
> > end  
> > =\> nil
> 
> > class C  
> > extend M  
> > end  
> > =\> C
> 
> > C.get  
> > =\> nil
> 
> > C.set(‘bla’)  
> > =\> “bla”
> 
> > C.get  
> > =\> “bla”
> 
> > class D \< C; end  
> > =\> nil
> 
> > D.get  
> > =\> nil

@x in this case is not a class variable, it is an instance variable of  
the singleton class of class C. You’ll find some information on that in  
the Pickaxe.

The notable difference compared to class variables proper is that class  
variables are shared in the inheritance hierarchy, whereas singleton  
class instance variables are not.

$ irb

> > class C  
> > def self.set(x)  
> > @@x = x  
> > end  
> > def self.get  
> > @@x  
> > end  
> > end  
> > =\> nil
> 
> > C.get  
> > NameError: uninitialized class variable @@x in C  
> > from (irb):6:in `get’  
> > from (irb):9
> 
> > C.set(‘bla’)  
> > =\> “bla”
> 
> > C.get  
> > =\> “bla”
> 
> > class D \< C; end  
> > =\> nil
> 
> > C.get  
> > =\> “bla”
> 
> > D.set(‘foo’)  
> > =\> “foo”
> 
> > C.get  
> > =\> “foo”

Michael

---

<div class="post-metadata">

**Author:** ![Brubix](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/f19dbf/32.png) [@Brubix](https://www.ruby-forum.com/u/Brubix)\
**Post date:** [December 17, 2007, 12:12pm UTC](https://www.ruby-forum.com/t/mixins-and-class-variables/123327/8 "2007-12-17T12:12:39Z")

</div>

On Dec 16, 9:14 pm, Michael S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Consider if class variables are really what you want.

You are totally right !  
It seems that what I wanted was just “instance variables of the  
singleton class”.

Nevertheless I found confusing the fact that they have the same sigil  
of “true” instance variables (single at) and, even worse (or  
better ;-), they don’t get mixed with instance variables with the same  
name.

Is there a place where this subject is fully explained (hopefully in  
simple terms) ?

Many thanks to all !

Brubix
