class Widget class << self def define(&block) DefinedBy::DSL(&block).map do |key, value, dsl_block| define_class(key.to_s.camelize, self).class_eval <<-EOF def initialize(attributes = {}) attributes[:name] ||= #{key.to_s.inspect} attributes[:description] ||= #{value.to_s.inspect} super(attributes) end EOF end end end attr_accessor :name, :description def initialize(attributes = {}) attributes.each do |key, value| self.send("#{key.to_s}=", value) end end end def Widget(&block) Widget.define(&block) end