From: Rick DeNatale Date: 2010-05-06T22:34:00+09:00 Subject: Re: Class variable "scope" 2010/5/6 Vinícius Baggio Fuentes : > Hi all, > > I've been writing a library for me to play with metaprogramming as an > exercise, but then I got stuck > on a non-metaprogramming issue: > > ## a.rb > class A >  def self.add_something(*sth) >    @@my_things ||= [] >    @@my_things << sth >  end > >  def self.my_things >    @@my_things >  end > end > > ## b.rb > require 'a' > > class B < A >  add_something :bag, :boots > end > require 'a' > > ## c.rb > class C < A >  add_something :sword, :shield > end > > The result, when requiring both c and b into an irb shell is, as expected: > > ruby-1.8.7-p249 > C.my_things >  => [[:bag, :boots], [:sword, :shield]] > ruby-1.8.7-p249 > B.my_things >  => [[:bag, :boots], [:sword, :shield]] > > I did achieve the following: > > C.my_things > [[:sword, :shield]] > B.my_things > [[:bag, :boots]] > > by moving my_things method into each child class and using the method on the > add_something method, but there must be a better way. How one could improve > this? Use a class instance variable rather than a class variable. Also I suspect you really want to get [:sword, :shield] rather than [[:sword, :shield]] class A def self.add_something(*sth) @my_things ||= [] @my_things.concat sth end def self.my_things @my_things end end class B < A add_something :bag, :boots end class C < A add_something :sword, :shield end B.my_things # => [:bag, :boots] C.my_things # => [:sword, :shield] If you really want to get a array of arrays rather than a single level array, just change the .concat back to << HTH -- Rick DeNatale Blog: http://talklikeaduck.denhaven2.com/ Github: http://github.com/rubyredrick Twitter: @RickDeNatale WWR: http://www.workingwithrails.com/person/9021-rick-denatale LinkedIn: http://www.linkedin.com/in/rickdenatale