Randy Kramer wrote:
(Sorry for the top posting.)
I'd like to take a shot at answering Lionel's original question (what is the difference between class and instance variables).
Oops, there is some confusion here: "class variable", "class instance variable" and "instance variable" are three different things.
@a in the context of instance code is an instance variable. "instance variable" is contained in an object, any object. As being internal to the object, it cannot be accessed from outside without a method call.
Code example:
class MyClass
def initialize # instance method
# instance code
@a = "value"
end
def a
@a
end
end
puts MyClass.new.a # output: value
@a in the context of class code is a "class instance variable". "class instance variable" is contained in an object, but not any one, it is contained in a class, as classes are objects too. Then, as being internal to the class object, it cannot be accessed from outside without a class method call.
Code example:
class MyClass
#class code
@a = "value"
def self.a # class method
# class code
@a
end
def a # instance method
# instance code
@a
end
end
puts MyClass.a # output: value
puts MyClass.new.a # output: nil
@@a whatever the context is a "class variable". "class variable" is "contained" in a class as if it was a "class instance variable" but without being one, it exists in "another world". In practical terms, the main difference is that '@@' is reachable from any instance without passing through any method call (which IMHO is poor OO design).
Code example:
class MyClass
# class code
@@a = 0
def incr # instance method
# instance code
@@a += 1
end
def a # instance method
# instance code
@@a
end
def self.incr # class method
# class code
@@a += 1
end
def self.a # class method
# class code
@@a
end
end
my_instance = MyClass.new
other_instance = MyClass.new
puts MyClass.a # output: 0
puts my_instance.a # output: 0
puts other_instance.a # output: 0
my_instance.incr
puts MyClass.a # output: 1
puts my_instance.a # output: 1
puts other_instance.a # output: 1
other_instance.incr
puts MyClass.a # output: 2
puts my_instance.a # output: 2
puts other_instance.a # output: 2
MyClass.incr
puts MyClass.a # output: 3
puts my_instance.a # output: 3
puts other_instance.a # output: 3
Is it ok?
Now, there is worse. @@a var is shared not only between the class and and its instances, but also with all inheriting classes and all their instances!
Guy Decoux showed things are different in 1.9.0, but I don't understand how it works.
···
--
Lionel Thiry