From: Gary Wright Date: 2011-03-08T14:43:05+09:00 Subject: Re: basic programming question, help please On Mar 7, 2011, at 11:31 PM, Eric Christopherson wrote: > On Mon, Mar 7, 2011 at 5:31 PM, Gary Wright wrote: >> >> class A >> @@a = "defined in A" >> end >> >> class B >> @@a = "defined in B" >> A.send(:define_method, :show_a) { @@a } >> A.send(:define_method, :show_x) { @@x } >> end >> >> class C < A >> end >> >> A.new.show_a # "defined in B" >> >> class Object >> @@x = 'defined in Object' >> end >> A.new.show_x # defined in Object" >> >> This shows that the resolution of class variables is based on the lexical >> scope and not the dynamic scope. The method #show_x also shows that >> the class hierarchy is also traversed when resolving a class variable (first B >> is considered and then Object because B is a subclass of Object) > > Interestingly, if you put > > @@x = "defined in B" > > in class B, A.new.show_x still shows "defined in Object". > You have to be very careful here if you are experimenting in irb, for example. Because class variables are actually unique within an entire subtree of the inheritance hierarchy the order and location in which the variable is defined is important. If you ran my sample code in irb you would have defined '@@x' in Object and effectively made it impossible to define any other '@@x' in any subclass of Object since the pre-existing '@@x' in Object would resolve for every subclass (because Object is the top of the hierarchy). On the other hand if you created '@@x' in B first then you could create another '@@x' in Object and they would be two different variables. The '@@x' in B would resolve for B and any of its descendants and the '@@x' in Object would resolve for Object and any of its descendants *except* for the subtree with B as its root. If you think this is complicated and somewhat confusing you are right. Most programmers expect Ruby's class variables to behave like C++'s or Java's class variables but they are very different. Gary Wright