I spent some time trying to find an answer to this but haven't found an
explanation I understand. Could someone tell me what is going on here:
module Mod
def self.append_features(base)
base.extend ClassMethods
super
end
module ClassMethods
def growl
puts @@donkey
end
end
end
class Animal
include Mod
@@donkey = "heyhaw"
def self.working_growl
puts @@donkey
end
end
# uninitialized class variable @@donkey in Mod::ClassMethods
Animal.growl
# works fine
Animal.working_growl
Now, in my limited understanding calling Animal.extend (or base in this
case) ClassMethods should have added growl as a class method to Animal,
equivalent to working_growl in scope (as it turns out self in both
methods is Animal which confuses me even more). Clearly this is not the
case. Any help would be appreciated. Thanks!
Class variables are lexically scoped--not dynamically scoped. This
means that @@donkey as it appears in Mod::ClassMethods#growl is associated
with Mod::ClassMethods and not with Animal even after you have
extended Animal and are executing Animal.growl. Since you have never
assigned a value to Mod::ClassMethods/@@donkey, Ruby complains.
This is very different from instance variables which are dynamically
scoped (i.e. resolved relative to 'self' at the time of execution).
So despite the fact that class variables and instance variables both
use a similar syntactical sigil (@@ vs @), they are scoped in vastly
different ways.
class variables: resolved at parse time relative to lexical scope
instance variables: resolved at execution time relative to 'self'
My advice is to just stay away from class variables entirely. Simply use
class instance variables instead.
Gary Wright
···
On Sep 21, 2007, at 6:53 PM, Got Ascii wrote:
I spent some time trying to find an answer to this but haven't found an
explanation I understand. Could someone tell me what is going on here:
module Mod
def self.append_features(base)
base.extend ClassMethods
super
end
module ClassMethods
def growl
puts @@donkey
end
end
end
class Animal
include Mod
@@donkey = "heyhaw"
def self.working_growl
puts @@donkey
end
end
# uninitialized class variable @@donkey in Mod::ClassMethods
Animal.growl
# works fine
Animal.working_growl
Now, in my limited understanding calling Animal.extend (or base in this
case) ClassMethods should have added growl as a class method to Animal,
equivalent to working_growl in scope (as it turns out self in both
methods is Animal which confuses me even more). Clearly this is not the
case. Any help would be appreciated. Thanks!
Class variables are not the same as class instance variables. This is one of those cases where you want a class instance variable. If you change @@donkey to @donkey, everything will work the way you want it to.
I wonder why you don't use the much simpler
<code>
module Mod
def growl
puts @donkey
end
end
class Animal
extend Mod @donkey = "hee-haw"
def self.working_growl
puts @donkey
end
end
</code>
which gives the same result. Maybe your code is a example reduced down from a much more complicated situation?
Regards, Morton
···
On Sep 21, 2007, at 6:53 PM, Got Ascii wrote:
I spent some time trying to find an answer to this but haven't found an
explanation I understand. Could someone tell me what is going on here:
module Mod
def self.append_features(base)
base.extend ClassMethods
super
end
module ClassMethods
def growl
puts @@donkey
end
end
end
class Animal
include Mod
@@donkey = "heyhaw"
def self.working_growl
puts @@donkey
end
end
# uninitialized class variable @@donkey in Mod::ClassMethods
Animal.growl
So despite the fact that class variables and instance variables both
use a similar syntactical sigil (@@ vs @), they are scoped in vastly
different ways.
I honestly wish that class variables looked like $$this, rather than
@@this. They're so completely unrelated to, and radically different
from, instance variables, whereas they're much more akin to globals.
The @/@@ thing has caused more confusion than anything else in Ruby, I
believe.
class variables: resolved at parse time relative to lexical scope
instance variables: resolved at execution time relative to 'self'
My advice is to just stay away from class variables entirely. Simply use
class instance variables instead.
I agree. If you want to maintain state per class, do it the way state
is normally maintained per object.
David
···
On Sat, 22 Sep 2007, Gary Wright wrote:
--
Upcoming training from Ruby Power and Light, LLC:
* Intro to Ruby on Rails, Edison, NJ, October 23-26
* Advancing with Rails, Edison, NJ, November 6-9
Both taught by David A. Black.
See http://www.rubypal.com for more info!
I'm in no place to disagree with David, but I should point out that $$
suggests superiority over $ globals.
My one cent.
Todd
···
On 9/22/07, David A. Black <dblack@rubypal.com> wrote:
Hi --
On Sat, 22 Sep 2007, Gary Wright wrote:
> So despite the fact that class variables and instance variables both
> use a similar syntactical sigil (@@ vs @), they are scoped in vastly
> different ways.
I honestly wish that class variables looked like $$this, rather than
@@this. They're so completely unrelated to, and radically different
from, instance variables, whereas they're much more akin to globals.
The @/@@ thing has caused more confusion than anything else in Ruby, I
believe.
No, I don't' think it is in the Pickaxe, at least not in the way I've
phrased it. I've found that most of the Ruby books I've looked at
do a terrible job at discussing class variable semantics.
Gary Wright
···
On Oct 2, 2007, at 9:27 AM, Got Ascii wrote:
Gary Wright wrote:
class variables: resolved at parse time relative to lexical scope
instance variables: resolved at execution time relative to 'self'
Cool, thank you this makes sense. My next question, is this information
in the pickaxe...did I just miss this?
Unless, of course, a person understands two symbols together to
represent a subset (like b has superiority over bb).
The @/@@ thing was really easy for me to understand right away because
I could separate them entirely. I wouldn't mind a different symbol
entirely, though.
Todd
···
On 9/22/07, Todd Benson <caduceass@gmail.com> wrote:
On 9/22/07, David A. Black <dblack@rubypal.com> wrote:
> Hi --
>
> On Sat, 22 Sep 2007, Gary Wright wrote:
>
> > So despite the fact that class variables and instance variables both
> > use a similar syntactical sigil (@@ vs @), they are scoped in vastly
> > different ways.
>
> I honestly wish that class variables looked like $$this, rather than
> @@this. They're so completely unrelated to, and radically different
> from, instance variables, whereas they're much more akin to globals.
> The @/@@ thing has caused more confusion than anything else in Ruby, I
> believe.
I'm in no place to disagree with David, but I should point out that $$
suggests superiority over $ globals.
So despite the fact that class variables and instance variables both
use a similar syntactical sigil (@@ vs @), they are scoped in vastly
different ways.
I honestly wish that class variables looked like $$this, rather than
@@this. They're so completely unrelated to, and radically different
from, instance variables, whereas they're much more akin to globals.
The @/@@ thing has caused more confusion than anything else in Ruby, I
believe.
I'm in no place to disagree with David, but I should point out that $$
suggests superiority over $ globals.
People in many places have disagreed with me, and I with them. Feel
free
At least $$this would point the confusion away from instance
variables, which are much more important and more deserving of not
being made confusing than globals. Not that I think confusion is good
in any direction. What I'd like most is for class variables to
disappear from Ruby, but I don't think that's going to happen.
David
···
On Sat, 22 Sep 2007, Todd Benson wrote:
On 9/22/07, David A. Black <dblack@rubypal.com> wrote:
On Sat, 22 Sep 2007, Gary Wright wrote:
--
Upcoming training from Ruby Power and Light, LLC:
* Intro to Ruby on Rails, Edison, NJ, October 23-26
* Advancing with Rails, Edison, NJ, November 6-9
Both taught by David A. Black.
See http://www.rubypal.com for more info!
The last sentence I agree with, because, while I was reading the
pickaxe -- well, with my lack of CS experience -- one of the biggest
questions in my mind was "why do we need class variables?". Kind of a
gut feeling thing, and not a logistical idea. Perhaps I need to read
more code to truly wrap my head around it. I wish I spoke Nihongo
Todd
···
On 9/22/07, David A. Black <dblack@rubypal.com> wrote:
People in many places have disagreed with me, and I with them. Feel
free
At least $$this would point the confusion away from instance
variables, which are much more important and more deserving of not
being made confusing than globals. Not that I think confusion is good
in any direction. What I'd like most is for class variables to
disappear from Ruby, but I don't think that's going to happen.
Really, I cannot recall
Anyway I am even more radical on this one, I'd wish class variables
simply went away.
Cheers
Robert
···
On 9/22/07, David A. Black <dblack@rubypal.com> wrote:
Hi --
On Sat, 22 Sep 2007, Todd Benson wrote:
> On 9/22/07, David A. Black <dblack@rubypal.com> wrote:
>> Hi --
>>
>> On Sat, 22 Sep 2007, Gary Wright wrote:
>>
>>> So despite the fact that class variables and instance variables both
>>> use a similar syntactical sigil (@@ vs @), they are scoped in vastly
>>> different ways.
>>
>> I honestly wish that class variables looked like $$this, rather than
>> @@this. They're so completely unrelated to, and radically different
>> from, instance variables, whereas they're much more akin to globals.
>> The @/@@ thing has caused more confusion than anything else in Ruby, I
>> believe.
>
> I'm in no place to disagree with David, but I should point out that $$
> suggests superiority over $ globals.
People in many places have disagreed with me, and I with them. Feel
free