DefinedBy
Advanced DSL and Dynamic class generation for Ruby
When do I is this?
- If you want to use a DSL to cut down on your code base
- If you need that DSL to create classes
- If you have a base class (e.g.
Widget
) and want to subclass it dozens of times but it's overkill to create separate classes for it manually. - Define template classes (default values for subclasses)
All at once
class Widget
class << self
def define(&block)
DefinedBy::DSL(&block).map do |key, value, dsl_block|
define_class(key, self).new(:name => key.to_s, :description => value)
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
widgets = Widget do
widget_a "This widget does X"
widget_b "This does Y"
end
puts widgets.inspect
#=> [
#<WidgetA:0x5c3348 @description="This widget does X", @name="widget_a">,
#<WidgetB:0x5c2970 @description="This does Y", @name="widget_b">
]
http://www.khelll.com/blog/ruby/stackoverflow-cool-ruby-questions-4/