Class variable "scope"

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?

Thanks in advance!

2010/5/6 Vinícius Baggio F. [email protected]:

@@my_things << sth
class B < A

[[: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: rubyredrick (Rick DeNatale) · GitHub
Twitter: @RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale

Great, much better, thanks for the reply, Rick!