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
···
--
Posted via http://www.ruby-forum.com/.
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, Roger Pack escribió:
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?
--
Iñaki Baz Castillo <ibc@aliax.net>
Roger Pack 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.
···
--
Posted via http://www.ruby-forum.com/\.
> 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?
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.
Take a look to this example which shows the same concept:
> class A
puts "I'm A"
end
I'm A
nil
> class B < A; end
nil
···
El Sábado, 19 de Diciembre de 2009, Iñaki Baz Castillo escribió:
El Sábado, 19 de Diciembre de 2009, Roger Pack escribió:
--
Iñaki Baz Castillo <ibc@aliax.net>
Hi --
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?
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.
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
···
On Sat, 19 Dec 2009, Iñaki Baz Castillo wrote:
El Sábado, 19 de Diciembre de 2009, Roger Pack escribió:
--
David A. Black
Senior Developer, Cyrus Innovation Inc.
THE COMPLEAT RUBYIST, Ruby training with Black/Brown/McAnally!
January 22-23, Tampa, Florida
Info and registration at http://www.thecompleatrubyist.com
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.
···
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.
--
Iñaki Baz Castillo <ibc@aliax.net>
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
···
--
Posted via http://www.ruby-forum.com/\.
Hi --
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
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
···
On Sun, 20 Dec 2009, Iñaki Baz Castillo wrote:
El Sábado, 19 de Diciembre de 2009, David A. Black escribió:
--
David A. Black
Senior Developer, Cyrus Innovation Inc.
THE COMPLEAT RUBYIST, Ruby training with Black/Brown/McAnally!
January 22-23, Tampa, Florida
Info and registration at http://www.thecompleatrubyist.com
Roger Pack wrote:
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?
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
=> nil
class B < A
def a2
@@a
end
def a2=(v)
@@a = v
end
end
=> nil
ai = A.new
=> #<A:0x7f59fb532260>
bi = B.new
=> #<B:0x7f59fb52cbf8>
bi.a2 = 1
=> 1
ai.a
NameError: uninitialized class variable @@a in A
from (irb):3:in `a'
from (irb):23
bi.a
NameError: uninitialized class variable @@a in A
from (irb):3:in `a'
from (irb):24
bi.a2
=> 1
bi.a = 2
=> 2
ai.a
=> 2
bi.a
=> 2
bi.a2
=> 1
ai.a = 3
=> 3
ai.a
=> 3
bi.a
=> 3
bi.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.
···
from :0
from :0
--
Posted via http://www.ruby-forum.com/\.
Hi --
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
···
On Sun, 20 Dec 2009, Roger Pack wrote:
--
David A. Black
Senior Developer, Cyrus Innovation Inc.
THE COMPLEAT RUBYIST, Ruby training with Black/Brown/McAnally!
January 22-23, Tampa, Florida
Info and registration at http://www.thecompleatrubyist.com