"Robert Klemme" <bob.news / gmx.net> schrieb im Newsbeitrag
news:2o3s2bF6m01rU1 / uni-berlin.de...

Now here's the class version - couldn't resist... :-)


class ItemClass
  def self.new
    cl = Class.new(self)
    cl.instance_variable_set "@operations", {}

    class <<cl
      attr_reader :operations

      def add_operation(name, *attrs, &code)
        @operations[name.to_sym] = Operation.new(*attrs, &code)
        self
      end

      def new(attributes)
        inst = allocate
        s_class = class<<inst ; self ; end

        attributes.each do |name, val|
          s_class.instance_eval do
            define_method name.to_sym do val end
          end
        end

        @operations.each do |name, op|
          if op.mandatory_attributes.all? {|attr| attributes.has_key?
attr}
            s_class.instance_eval do
              define_method name.to_sym, &op.code
            end
          end
        end

        inst
      end
    end

    cl
  end

end

class Operation
  attr_reader :mandatory_attributes, :code

  def initialize(*attributes, &code)
    @mandatory_attributes = attributes
    @code = code
  end
end

# ----------------------------------------------

cl = ItemClass.new

cl.add_operation(:print_name, :name) do
  puts self.name
end

cl.add_operation(:print_size, :size) do
  puts self.attributes[:size]
end

inst = cl.new(:name => "foo")
inst.print_name # "foo"
inst.print_size # NameError


Kind regards

    robert