Question re: modules and class variable scope

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!

On Sep 21, 2007, at 6:53 PM, Got Ascii wrote:

module ClassMethods
def self.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 W.

On Sep 21, 2007, at 6:53 PM, Got Ascii wrote:

module ClassMethods
def self.working_growl
puts @@donkey
end
end

uninitialized class variable @@donkey in Mod::ClassMethods

Animal.growl

works fine

Animal.working_growl

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

module Mod def growl puts @donkey end end

class Animal
extend Mod
@donkey = “hee-haw”
def self.working_growl
puts @donkey
end
end

which gives the same result. Maybe your code is a example reduced
down from a much more complicated situation?

Regards, Morton

On 9/22/07, David A. Black [email protected] wrote:

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.

My one cent.

Todd

On 9/22/07, Todd B. [email protected] wrote:

@@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.

My one cent.

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

Hi –

On Sat, 22 Sep 2007, Gary W. 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.

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 9/22/07, David A. Black [email protected] wrote:

David

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 :slight_smile:

Todd

Gary W. 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?

Hi –

On Sat, 22 Sep 2007, Todd B. wrote:

@@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 :slight_smile:

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 Oct 2, 2007, at 9:27 AM, Got Ascii wrote:

Gary W. 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?

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 W.

On 9/22/07, David A. Black [email protected] wrote:

use a similar syntactical sigil (@@ vs @), they are scoped in vastly

People in many places have disagreed with me, and I with them. Feel
free :slight_smile:
Really, I cannot recall :wink:
Anyway I am even more radical on this one, I’d wish class variables
simply went away.

Cheers
Robert