Writing a DSL in Ruby
When defining a simple DSL instance_eval and instance_exec is your friend:
class Worker
attr_reader :where
def call(where, &block)
@where = where
instance_eval &block
end
def cut_trees
puts "Cutting trees"
end
def make_planks
puts "Making planks"
end
def i(what, &block)
instance_eval &block
end
end
def work where, &block
puts "Working #{where}"
Worker.new.(where, &block)
puts "Going home"
end
Use the DSL like this:
work "in the woods" do
cut_trees
make_planks
i "take a coffee break" do
puts "Cooking coffee #{where}"
end
end
Output is:
Working in the woods
Cutting trees
Making planks
Cooking coffee in the woods
Going home
instance_exec method allows you to pass arguments to your blocks, which instance_eval doesn't allow.