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