From: Sam Hendley Date: 2008-08-21T03:26:57+09:00 Subject: Alternatives to class variables Hello, this is my first post to this list and I have only been using ruby for a couple of weeks so forgive me if its overly simple, I spent a few hours searching and wasn't able to figure this out myself. What I am trying to do is use some meta-programming techniques to create a simple DSL that allows me to define functions dynamically and collect other information that I can iterate over. I have an implementation that is using "Class Variables" that is working but I have to specify all of the functions that use the @@ variables in all of the subclasses which violates DRY and my sensiblities. What I am looking for is a way to have subclass specific information used by a common class. Below is the implementation I have (boiled down to its simplest possible form with a testcase to show the behavior I need). I know there must be a better way to do this but my ruby-fu is not up to the task yet, im really interested to see what the idiomatic ruby way to do this is. Sam Hendley ------------ Example.rb -------------- require 'test/unit' module MethodCollector def self.included( klass) klass.extend ClassMethods end module ClassMethods def addpoint(array_name, name) is_defined = send(:class_variable_defined?, array_name) if !is_defined arr = Array.new send(:class_variable_set, array_name, arr) elsif arr = send(:class_variable_get,array_name) end arr << name end def add_method(name) method_name = (name.to_s).to_sym self.send :define_method, method_name do "MethodName is: #{method_name}" end addpoint(:@@extra_methods, name) end end end class MethodAdderBase include MethodCollector # ideally I would define this method (and any others with other common functionality that # use the "class specific" variables #def extra_methods # @@extra_methods #end end class Foo < MethodAdderBase add_method :foo_1 add_method :foo_2 add_method :foo_3 def extra_methods @@extra_methods end end class Bar < MethodAdderBase add_method :bar_1 add_method :bar_2 add_method :bar_3 add_method :bar_4 def extra_methods @@extra_methods end end class Check < Test::Unit::TestCase def test_methods_created foo = Foo.new bar = Bar.new assert_equal(foo.foo_1, "MethodName is: foo_1") assert_equal(bar.bar_1, "MethodName is: bar_1") end def test_methods_collected foo = Foo.new bar = Bar.new assert_equal(foo.extra_methods.size, 3) assert_equal(bar.extra_methods.size, 4) end end -- Posted via http://www.ruby-forum.com/.