This confused me a bit
class A
@a = 2
@@a = 3
def self.a
puts [@a, @@a]
end
end
class B < A; end
A.a # [2, 3]
B.a # [nil, 3]
shouldn’t @a just lookup @@a in the parent? Different treatment for
different types of variables?
-r
This confused me a bit
class A
@a = 2
@@a = 3
def self.a
puts [@a, @@a]
end
end
class B < A; end
A.a # [2, 3]
B.a # [nil, 3]
shouldn’t @a just lookup @@a in the parent? Different treatment for
different types of variables?
-r
El Sábado, 19 de Diciembre de 2009, Roger P. escribió:
class B < A; end
A.a # [2, 3]
B.a # [nil, 3]shouldn’t @a just lookup @@a in the parent? Different treatment for
different types of variables?
When you write:
class A
@a = 2
take into account that @a=2 is just parsed when loading class A for
first
time.
When you later do “class B < A; end”, the Ruby interpreter doesn’t read
the
line “@a = 2” again as it already parsed class A and just stored in
memory the
methods of class A.
El Sábado, 19 de Diciembre de 2009, Iñaki Baz C. escribió:
class A
@a = 2take into account that @a=2 is just parsed when loading class A for first
time.
When you later do “class B < A; end”, the Ruby interpreter doesn’t read the
line “@a = 2” again as it already parsed class A and just stored in memory
the methods of class A.
Take a look to this example which shows the same concept:
irb> class A
puts “I’m A”
end
I’m A
nil
irb> class B < A; end
nil
Hi –
On Sat, 19 Dec 2009, Iñaki Baz C. wrote:
class A
@a = 2take into account that @a=2 is just parsed when loading class A for first
time.
When you later do “class B < A; end”, the Ruby interpreter doesn’t read the
line “@a = 2” again as it already parsed class A and just stored in memory the
methods of class A.
Also, instance variables are always pegged to “self”.
class A
puts self # A
@x = 1
end
class B < A
puts self # B
puts @x # nil
end
Every object, including every Class object, has its own supply of
instance variable “slots”, and the meaning of @var is always
self.instance_variable_get("@var").
David
Hi –
On Sat, 19 Dec 2009, Roger P. wrote:
class B < A; end
A.a # [2, 3]
B.a # [nil, 3]shouldn’t @a just lookup @@a in the parent? Different treatment for
different types of variables?
I think you mean shouldn’t it just look up @a (not @@a) in the parent
– and the answer is no A and B are different objects, and
therefore do not share instance variables.
David
Roger P. wrote:
shouldn’t @a just lookup @@a in the parent?
Nope - class variables (@@) have nothing to do with instance variables
(@). @a in this case is just an instance variable of the class object,
so @a in class B is different to @a in class A
Class variables are a very strange beast with bizarre semantics. I would
avoid them if I were you.
El Sábado, 19 de Diciembre de 2009, David A. Black
escribió:> I think you mean shouldn’t it just look up @a (not @@a) in the parent
– and the answer is no A and B are different objects, and
therefore do not share instance variables.
class A
@a = “hello”
def self.say
puts defined?(@a).inspect
end
end
A.say
=> “instance-variable”
nil
class B < A ; end
B.say
nil
nil
But as I already explained, the line ‘@a = “hello”’ is just parsed by
Ruby
interpreter when loading class A.
When creating class B (which inherits from A) the Ruby parser doesn’t
read the
whole class A definition again. Instead it already has in memory all the
class/instance methods defined for class A so it wouldn’t read ‘@a =
“hello”’
anymore.
And because of it, B class object doesn’t know @a as its instance
variable, it
knows nothing about @a.
Hi –
On Sun, 20 Dec 2009, Iñaki Baz C. wrote:
end
nil
Exactly
But as I already explained, the line ‘@a = “hello”’ is just parsed by Ruby
interpreter when loading class A.When creating class B (which inherits from A) the Ruby parser doesn’t read the
whole class A definition again. Instead it already has in memory all the
class/instance methods defined for class A so it wouldn’t read ‘@a = “hello”’
anymore.And because of it, B class object doesn’t know @a as its instance variable, it
knows nothing about @a.
The general rule about instance variables (that they are strictly
per-object) is still in effect, though, even if you do it some other
way:
class A
end
class B < A
end
A.instance_variable_set("@a", “hello”)
p B.instance_variable_get("@a") # nil
David
Class variables are a very strange beast with bizarre semantics. I would
avoid them if I were you.
Yeah they must be special cased so that beginning users can use them
with abandon and it will “just work.”
Interesting.
in
class A
@@a = 3
end
class B < A
def go
@@a
end
end
in B.new.go => 3…where is @@a stored?..it’s not in B…it’s not in
A’s nearest ancestor, which is “Object”…it’s special cased somehow?
Roughly paraphrasing a quote I heard once…
“after using ruby for 5 years, it is still surprising to me” (no offence
intended, of course
Cheers.
-r
Roger P. wrote:
class A
@@a = 3
endclass B < A
def go
@@a
end
endin B.new.go => 3…where is @@a stored?..it’s not in B…it’s not in
A’s nearest ancestor, which is “Object”…it’s special cased somehow?
I believe it’s picking up the value from class A, since that’s B’s
ancestor, and B doesn’t already have an @@a of its own.
It gets scarier though. Have a look at this:
class A
def a
@@a
end
def a=(v)
@@a = v
end
end
=> nilclass B < A
def a2
@@a
end
def a2=(v)
@@a = v
end
end
=> nilai = A.new
=> #<A:0x7f59fb532260>bi = B.new
=> #<B:0x7f59fb52cbf8>bi.a2 = 1
=> 1ai.a
NameError: uninitialized class variable @@a in A
from (irb):3:in `a’
from (irb):23
from :0bi.a
NameError: uninitialized class variable @@a in A
from (irb):3:in `a’
from (irb):24
from :0bi.a2
=> 1bi.a = 2
=> 2ai.a
=> 2bi.a
=> 2bi.a2
=> 1ai.a = 3
=> 3ai.a
=> 3bi.a
=> 3bi.a2
=> 1
So which ‘version’ of the @@a class variable you see, depends on where
the method which reads it was defined… or something like that.
Hi –
On Sun, 20 Dec 2009, Roger P. wrote:
Class variables are a very strange beast with bizarre semantics. I would
avoid them if I were you.Yeah they must be special cased so that beginning users can use them
with abandon and it will “just work.”
See this, from Matz:
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/347355
especially:
(3) and lastly, and most importantly, do not use class variables,
unless you really really need them; they are fundamentally global
variables.
That’s the thing; they’re really hierarchy globals, but confusingly
similar to instance variables (of which they are essentially the
opposite) in appearance.
David
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.
Sponsor our Newsletter | Privacy Policy | Terms of Service | Remote Ruby Jobs