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