Forum: Ruby Class instance variables, class variables and constants

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
D521c0db52fe0b14d799dd669d536098?d=identicon&s=25 Tony Mobily (Guest)
on 2006-02-20 15:23
(Received via mailing list)
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
18ca239ffade6df0b839d26062f173fb?d=identicon&s=25 Dominik Bathon (Guest)
on 2006-02-20 17:13
(Received via mailing list)
On Mon, 20 Feb 2006 15:22:04 +0100, Tony Mobily <merc@mobily.com> 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, ::A::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, ::A::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
D521c0db52fe0b14d799dd669d536098?d=identicon&s=25 Tony Mobily (Guest)
on 2006-02-20 23:36
(Received via mailing list)
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.
430ea1cba106cc65b7687d66e9df4f06?d=identicon&s=25 David Vallner (Guest)
on 2006-02-21 03:38
(Received via mailing list)
DÅ?a Pondelok 20 Február 2006 23:35 Tony Mobily 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 Vallner
430ea1cba106cc65b7687d66e9df4f06?d=identicon&s=25 David Vallner (Guest)
on 2006-02-21 03:41
(Received via mailing list)
DÅ?a Pondelok 20 Február 2006 15:22 Tony Mobily 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 Vallner
1fba4539b6cafe2e60a2916fa184fc2f?d=identicon&s=25 unknown (Guest)
on 2006-02-21 04:06
(Received via mailing list)
Hi --

On Tue, 21 Feb 2006, Dominik Bathon 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/...


David

--
David A. Black (dblack@wobblini.net)
Ruby Power and Light (http://www.rubypowerandlight.com)

"Ruby for Rails" chapters now available
from Manning Early Access Program! http://www.manning.com/books/black
This topic is locked and can not be replied to.