# Class instance variables, class variables and constants

**URL:** <https://www.ruby-forum.com/t/class-instance-variables-class-variables-and-constants/70867>\
**Category:** Ruby\
**Created:** [February 20, 2006, 3:23pm UTC](https://www.ruby-forum.com/t/class-instance-variables-class-variables-and-constants/70867 "2006-02-20T15:23:33Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![merc](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/f07891/32.png) [@merc](https://www.ruby-forum.com/u/merc)\
**Post date:** [February 20, 2006, 3:23pm UTC](https://www.ruby-forum.com/t/class-instance-variables-class-variables-and-constants/70867/1 "2006-02-20T15:23:33Z")

</div>

Hello,

Thanks to the code in attach, I’ve figured out what is now completely  
obvious to me:

CLASS VARIABLE (@@something)

- Inherited by subclasses
- SAME ALLOCATION: If it’s changed in Child, then it will change in  
Parent

CONSTANTS (Something)

- Inherited by subclasses
- PRIVATE ALLOCATION: If it’s changed in Child, it will NOT change in  
parent

CLASS INSTANCE VARIABLES (@something)

- NOT Inherited by subclasses. They will simply be nil. Scope = Class
- DIFFERENT ALLOCATION: If it’s changed in Child, it will NOT change  
in parent

I am sending this email to the mailing list so that if some Ruby  
newbie has the same problem with variable scope, they might find this  
email (and find it useful).

David A. Black wrote:

“I think Matz is planning to change class variables in 2.0 so that they  
are class/module scoped rather than hierarchy scoped.”

But wouldn’t it make class variables (@@something) the same as class  
instance variables (@something)?

Here’s the code I used to figure things out:

* * *

#!/usr/local/bin/ruby -w

class Outer  
@@class\_var=10  
GlobalVar=100  
@civ=1000

```
     class Second < Outer

             @@class_var=11
             GlobalVar=101
             @civ=1001

             def Second::class_var
                     @@class_var
             end

             def Second::class_var=(what)
                     @@class_var=what
             end

             def Second::civ
                     @civ
             end

             def Second::civ=(what)
                     @civ=what
             end

     end

     def Outer::class_var
             return @@class_var
     end

     def Outer::class_var=(what)
             @@class_var=what
     end

     def Outer::civ
             @civ
     end

     def Outer::civ=(what)
             @civ=what
     end

```

end

class Third \< Outer

```
     def self::class_var
             return @@class_var
     end

     def Third::class_var=(what)
             @@class_var=what
     end

     def Third::class_var
             @@class_var
     end

     def Third::class_var=(what)
             @@class_var=what
     end

     def Third::civ
             @civ
     end

     def Third::civ=(what)
             @civ=what
     end

```

end

puts “Outer”  
p Outer::class\_var  
p Outer::GlobalVar  
p Outer::civ  
puts “Outer::Second”  
p Outer::Second::class\_var  
p Outer::Second::GlobalVar  
p Outer::Second::civ  
puts “Third”  
p Third::class\_var  
p Third::GlobalVar  
p Third::civ  
puts  
puts

Outer::Second::class\_var=13  
Outer::Second::GlobalVar=103  
Outer::Second::civ=1003

puts “Outer”  
p Outer::class\_var  
p Outer::GlobalVar  
p Outer::civ  
puts “Outer::Second”  
p Outer::Second::class\_var  
p Outer::Second::GlobalVar  
p Outer::Second::civ  
puts “Third”  
p Third::class\_var  
p Third::GlobalVar  
p Third::civ  
puts  
puts

Third::class\_var=14  
Third::GlobalVar=104  
Third::civ=1004

puts “Outer”  
p Outer::class\_var  
p Outer::GlobalVar  
p Outer::civ  
puts “Outer::Second”  
p Outer::Second::class\_var  
p Outer::Second::GlobalVar  
p Outer::Second::civ  
puts “Third”  
p Third::class\_var  
p Third::GlobalVar  
p Third::civ  
puts  
puts

# Just checking…

p Third::Second::class\_var  
p Third::Second::GlobalVar  
p Third::Second::civ

---

<div class="post-metadata">

**Author:** ![merc](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/f07891/32.png) [@merc](https://www.ruby-forum.com/u/merc)\
**Post date:** [February 20, 2006, 5:13pm UTC](https://www.ruby-forum.com/t/class-instance-variables-class-variables-and-constants/70867/2 "2006-02-20T17:13:35Z")

</div>

On Mon, 20 Feb 2006 15:22:04 +0100, Tony M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> CONSTANTS (Something)
> 
> - Inherited by subclasses
> - PRIVATE ALLOCATION: If it’s changed in Child, it will NOT change in  
> parent
> 
> CLASS INSTANCE VARIABLES (@something)
> 
> - NOT Inherited by subclasses. They will simply be nil. Scope = Class
> - DIFFERENT ALLOCATION: If it’s changed in Child, it will NOT change in  
> parent

But there is more fun when singleton classes get involved:

class A  
@@var = :A  
C = :CA  
end

class B  
@@var = :B  
C = :CB

a = A.new  
class ::A  
p [@@var, C] # =\> [:A, :CA]  
def foo  
[@@var, C]  
end  
end  
def a.bar  
[@@var, C]  
end  
class \<\< a  
p [@@var, C] # =\> [:B, :CB]  
def baz  
[@@var, C]  
end  
end  
p a.foo # =\> [:A, :CA]  
p a.bar # =\> [:B, :CB]  
p a.baz # =\> [:B, :CB]  
p [@@var, :🅰:C, C, class \<\< a;C;end] # =\> [:B, :CA, :CB, :CB]  
class \<\< a  
@@var = :ASing # this changes B’s @@var [\*]  
C = :CASing # this creates a new C for a’s sing. class  
end  
p [@@var, :🅰:C, C, class \<\< a;C;end] # =\> [:ASing, :CA, :CB,  
:CASing]  
p a.foo # =\> [:A, :CA]  
p a.bar # =\> [:ASing, :CB]  
p a.baz # =\> [:ASing, :CASing]  
end

Some points:

- singleton classes don’t have their own class variables, but they can  
have their own constants
- constant and class var lookup use the lexical scope, so it depends  
“where” you do something (that’s why bar’s C and baz’s C are different)
- (lexical) singleton-class-scopes are skipped when accessing class vars  
(that’s why [\*] changes B’s @@var and not A’s @@var)

I hope that helps and doesn’t totally confuse you 😉

Dominik

---

<div class="post-metadata">

**Author:** ![merc](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/f07891/32.png) [@merc](https://www.ruby-forum.com/u/merc)\
**Post date:** [February 20, 2006, 11:36pm UTC](https://www.ruby-forum.com/t/class-instance-variables-class-variables-and-constants/70867/3 "2006-02-20T23:36:08Z")

</div>

Hi,

> Some points:
> 
> - singleton classes don’t have their own class variables, but they  
> can have their own constants
> - constant and class var lookup use the lexical scope, so it  
> depends “where” you do something (that’s why bar’s C and baz’s C  
> are different)
> - (lexical) singleton-class-scopes are skipped when accessing class  
> vars (that’s why [\*] changes B’s @@var and not A’s @@var)
> 
> I hope that helps and doesn’t totally confuse you 😉

OK. One hour later, this is became clear…  
I’d write the points above in a different order:

- singleton classes can have their own constants

- singleton classes don’t have their own class variables. (Lexical)  
singleton-class-scopes are skipped when accessing class vars

- constant and class variable lookup use the lexical scope, so it  
depends “where” you do something

Now… I do have a question. On one hand, I really, really want to  
know all these fine details. That’s just my nature.  
However, in this case, I must ask: is this going to be _useful_ at  
any point in time?  
When would you want to set a constant for a singleton class?

The rest makes perfect sense to me: a singleton class could  
realistically need access a class variable. And I realise that I need  
to know that constant and class variable lookup use the lexical  
scope. But… singleton constants…?

Just curious!

Merc.

---

<div class="post-metadata">

**Author:** ![merc](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/f07891/32.png) [@merc](https://www.ruby-forum.com/u/merc)\
**Post date:** [February 21, 2006, 3:38am UTC](https://www.ruby-forum.com/t/class-instance-variables-class-variables-and-constants/70867/4 "2006-02-21T03:38:34Z")

</div>

DÅ?a Pondelok 20 FebruÃ¡r 2006 23:35 Tony M. napÃ­sal:

> When would you want to set a constant for a singleton class?

Hardly ever? It’s not like you need more instances to always get the  
same  
value.

David V.

---

<div class="post-metadata">

**Author:** ![merc](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/f07891/32.png) [@merc](https://www.ruby-forum.com/u/merc)\
**Post date:** [February 21, 2006, 3:41am UTC](https://www.ruby-forum.com/t/class-instance-variables-class-variables-and-constants/70867/5 "2006-02-21T03:41:46Z")

</div>

DÅ?a Pondelok 20 FebruÃ¡r 2006 15:22 Tony M. napÃ­sal:

> “I think Matz is planning to change class variables in 2.0 so that they  
> are class/module scoped rather than hierarchy scoped.”
> 
> But wouldn’t it make class variables (@@something) the same as class  
> instance variables (@something)?

Nope. Class variables could still be “inherited”, but they wouldn’t  
clobber  
stuff up the hierarchy if modified.

David V.

---

<div class="post-metadata">

**Author:** ![merc](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/f07891/32.png) [@merc](https://www.ruby-forum.com/u/merc)\
**Post date:** [February 21, 2006, 4:06am UTC](https://www.ruby-forum.com/t/class-instance-variables-class-variables-and-constants/70867/6 "2006-02-21T04:06:09Z")

</div>

Hi –

On Tue, 21 Feb 2006, Dominik B. wrote:

> Some points:
> 
> - singleton classes don’t have their own class variables, but they can have  
> their own constants

There’s an interesting discussion of this in an earlier thread; see  
especially:  
[http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/65527](http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/65527)

David

–  
David A. Black (removed\_email\_address@domain.invalid)  
Ruby Power and Light ([http://www.rubypowerandlight.com](http://www.rubypowerandlight.com))

“Ruby for Rails” chapters now available  
from Manning Early Access Program! [Ruby for Rails](http://www.manning.com/books/black)
