What is really a class instance variable compare to a class

Hi all,

Given the following definition :

class A
@@class_var = “a class variable”
@class_instance_var = “a class instance variable”

def a_method
   @instance_var = "an instance variable"
end

end

I understand what is a class variable and what is an instance
variable. The problem I have is what is a class instance variable like
@class_instance_var ? Where does this variable live ?

A class variable is shared by all instances of the class. But what
about the class instance variable ?

Thanks for any explanation.

CM.

HI –

On Fri, 9 Feb 2007, Ruby A. wrote:

end
end

I understand what is a class variable and what is an instance
variable. The problem I have is what is a class instance variable
like @class_instance_var ? Where does this variable live ?

A class variable is shared by all instances of the class. But what
about the class instance variable ?

Every instance variable you ever see belongs to whatever object is, at
the moment you see the instance variable, playing the role of ‘self’.
Inside a class definition block, ‘self’ is the class object itself:

class A
p self # A
end

So if you have an instance variable at that point in execution:

class A
@x = 1
end

it belongs to the object A, which is a class object.

Similarly, that variable @x will only be visible when self is A. When
self is not A, @x will not be that same instance variable. You can
always establish ownership of instance variables by calculating what
self is at the point that the instance variable appears.

Keep in mind, too, that the phrase “class instance variable” is just a
way of clarifying that you don’t mean “instance variable defined in
this class’s instance methods”. There’s no separate “class instance
variable” construct at the language level; there are just objects,
some of which are class objects and all of which can be self and
therefore have instance variables.

David

On Fri, Feb 09, 2007 at 07:48:37PM +0900, Ruby A. wrote:

=> So, an object instance variable is shared/seen by the derived object instances.

My understanding is:

(1) An instance variable is only visible to that object. It doesn’t
matter
what “class” the object is. It’s not visible by any other objects,
either of
the same class or a different class.

(2) A class instance variable is an instance variable of an object which
happens to be a class (its an object whose class is “Class”). This is
also
private to that object, i.e. to the class. A subclass is a different
object,
so has its own class instance variables.

(3) Class variables, i.e. @@foo, are voodoo. But yes I believe they are
shared by groups of classes in the same ancestry somehow.

B.

David,

Thanks a lot for your reply. But this raises another understanding
problem for me. It seems that regarding inheritance there are different
behaviours for :

  • an object instance variable
  • a class variable
  • a class instance variable

For the following code (I’m running Ruby 1.8.5p12) :

class TestObject
def initialize
@var = “an object instance variable”
end
def print
puts @var
end
end
class DerivedTestObject < TestObject
def set_var
@var = “an object instance variable : changed”
end
end

o = DerivedTestObject.new
o.print
o.set_var
o.print

The output is :
an object instance variable
an object instance variable : changed

=> So, an object instance variable is shared/seen by the derived
object instances.

For the following code :

class TestClass
@@var = “a class variable”
@var = “a class instance variable”
def self.print
puts @@var
puts @var
end
end
class DerivedTestClass < TestClass
def self.set_var
@@var = “a class variable : changed”
@var = “a class instance variable : changed”
end
end
TestClass.print
puts “-------------”
DerivedTestClass.print
puts “-------------”
DerivedTestClass.set_var
DerivedTestClass.print
puts “-------------”
TestClass.print

The output is :
a class variable
a class instance variable

a class variable
nil

a class variable : changed
a class instance variable : changed

a class variable : changed
a class instance variable

=> So, a class variable is shared/seen by derived classes (similar
behaviour as an instance variable). Conversely, a class instance
variable is not shared/seen by derived classes.

Am I missing something ?

Another question :
The inheritance of a class variable and a class method is really great
:-).
Is it going to be removed in Ruby 2.0 ? I heard something about that
but I hope not.

Thanks for any explanation.

CM.

[email protected] wrote:
HI –

On Fri, 9 Feb 2007, Ruby A. wrote:

end
end

I understand what is a class variable and what is an instance
variable. The problem I have is what is a class instance variable
like @class_instance_var ? Where does this variable live ?

A class variable is shared by all instances of the class. But what
about the class instance variable ?

Every instance variable you ever see belongs to whatever object is, at
the moment you see the instance variable, playing the role of ‘self’.
Inside a class definition block, ‘self’ is the class object itself:

class A
p self # A
end

So if you have an instance variable at that point in execution:

class A
@x = 1
end

it belongs to the object A, which is a class object.

Similarly, that variable @x will only be visible when self is A. When
self is not A, @x will not be that same instance variable. You can
always establish ownership of instance variables by calculating what
self is at the point that the instance variable appears.

Keep in mind, too, that the phrase “class instance variable” is just a
way of clarifying that you don’t mean “instance variable defined in
this class’s instance methods”. There’s no separate “class instance
variable” construct at the language level; there are just objects,
some of which are class objects and all of which can be self and
therefore have instance variables.

David


Q. What is THE Ruby book for Rails developers?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black)
(See what readers are saying! http://www.rubypal.com/r4rrevs.pdf)
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)

Hi –

On Fri, 9 Feb 2007, Ruby A. wrote:

David,

Thanks a lot for your reply. But this raises another understanding problem for me. It seems that regarding inheritance there are different behaviours for :

  • an object instance variable
  • a class variable
  • a class instance variable

You’ve got two very different things there:

  • instance variables
  • class variables

Instance variables all behave alike. Class variables are completely
different, and unrelated. It’s best not to go into it expecting any
similarity.

class DerivedTestObject < TestObject
The output is :
an object instance variable
an object instance variable : changed

=> So, an object instance variable is shared/seen by the derived
object instances.

Not exactly. Every object has its own instance variables, which are
not seen by any other object. Your DerivedTestObject instance
executes the initialize method, and inside that method, its instance
variable @var is initialized. In set_var, that variable is changed.

The fact that initialize is defined in a superclass doesn’t mean
anything. When initialize is executed, ‘self’ is the new
DerivedTestObject instance. So @var, when it appears in that method,
belongs to that instance.

It’s better always to think of instance variables in terms of what
object is ‘self’ at the moment the instance variable appears. An
instance variable has no knowledge of class or inheritance; it only
knows ‘self’.

class DerivedTestClass < TestClass
DerivedTestClass.print
a class variable : changed
a class instance variable : changed

a class variable : changed
a class instance variable

=> So, a class variable is shared/seen by derived classes (similar
behaviour as an instance variable). Conversely, a class instance
variable is not shared/seen by derived classes.

No instance variable is shared with any other object. TestClass and
DerivedTestClass are two different objects; therefore, they do not
share instance variables. Again, instance variables have no concept
of “class” or “inheritance”. They simply adhere to the object in
whose context as ‘self’ they are created.

Am I missing something ?

Another question :
The inheritance of a class variable and a class method is really great :-).
Is it going to be removed in Ruby 2.0 ? I heard something about
that but I hope not.

My current understanding is that class variables will be visible only
to the class or module they’re defined in, including instance methods
of that class or module. I have mixed emotions about this. I would
actually rather see them disappear. My experience over the years is
that they cause more confusion than they’re worth, and that in 2.0
they’re going to be almost like instance variables of class objects
but not quite… and therefore people are still going to wonder what’s
going on and why it has to be there. (At least, I will :slight_smile:

David

Brian, David,

Thanks a lot for your replies.
It’s now crystal clear for me.

David,

Your book is excellent !
May be you can add these additional explanations in a next revision
:-)!

CM.

[email protected] wrote:
Hi –

On Fri, 9 Feb 2007, Ruby A. wrote:

David,

Thanks a lot for your reply. But this raises another understanding problem for me. It seems that regarding inheritance there are different behaviours for :

  • an object instance variable
  • a class variable
  • a class instance variable

You’ve got two very different things there:

  • instance variables
  • class variables

Instance variables all behave alike. Class variables are completely
different, and unrelated. It’s best not to go into it expecting any
similarity.

class DerivedTestObject < TestObject
The output is :
an object instance variable
an object instance variable : changed

=> So, an object instance variable is shared/seen by the derived
object instances.

Not exactly. Every object has its own instance variables, which are
not seen by any other object. Your DerivedTestObject instance
executes the initialize method, and inside that method, its instance
variable @var is initialized. In set_var, that variable is changed.

The fact that initialize is defined in a superclass doesn’t mean
anything. When initialize is executed, ‘self’ is the new
DerivedTestObject instance. So @var, when it appears in that method,
belongs to that instance.

It’s better always to think of instance variables in terms of what
object is ‘self’ at the moment the instance variable appears. An
instance variable has no knowledge of class or inheritance; it only
knows ‘self’.

class DerivedTestClass < TestClass
DerivedTestClass.print
a class variable : changed
a class instance variable : changed

a class variable : changed
a class instance variable

=> So, a class variable is shared/seen by derived classes (similar
behaviour as an instance variable). Conversely, a class instance
variable is not shared/seen by derived classes.

No instance variable is shared with any other object. TestClass and
DerivedTestClass are two different objects; therefore, they do not
share instance variables. Again, instance variables have no concept
of “class” or “inheritance”. They simply adhere to the object in
whose context as ‘self’ they are created.

Am I missing something ?

Another question :
The inheritance of a class variable and a class method is really great :-).
Is it going to be removed in Ruby 2.0 ? I heard something about
that but I hope not.

My current understanding is that class variables will be visible only
to the class or module they’re defined in, including instance methods
of that class or module. I have mixed emotions about this. I would
actually rather see them disappear. My experience over the years is
that they cause more confusion than they’re worth, and that in 2.0
they’re going to be almost like instance variables of class objects
but not quite… and therefore people are still going to wonder what’s
going on and why it has to be there. (At least, I will :slight_smile:

David


Q. What is THE Ruby book for Rails developers?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black)
(See what readers are saying! http://www.rubypal.com/r4rrevs.pdf)
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)

hi there,

not to hijack the thread or anything, but since it´s about class
variables.

i write a lot of rails plugins and i use class variables a lot when
doing mixins that need to have values propagated to the class that is
getting the module mixed in.

like this:

class Foo
end

module Bar
@@a = “some value”
A = “some other value”

    def classvar
            return @@a
    end
    def classconst
            return A
    end

end

dup = Foo.new
dup.extend Bar
puts dup.classvar
puts dup.classconst

i find class variables really useful for that. on the other hand like in
my code you could always use class constants which pretty much do the
same in my understanding (please correct me if i´m wrong here)

just wanted to show this as a valid (at least from my perspective) use
case for class variables.

kind regards,

alexander