A Domain Specific Language (DSL) is a computer language targeted to a particular kind of problem or application domain. There are various ways to implement a DSL in Ruby: classic blocks, instance_eval or mixins and extend. Most often instance_eval is used. How does it work? First one has to define the DSL itself, for example in a class like the this:
class MyDsl
def initialize
@local_var = 1
end
def method_1
puts "#{@local_var}+1=#{@local_var += 1}"
end
def method_2
puts "says your DSL method"
end
end
then one can apply the dsl to an object:
MyClass.apply_dsl(MyDSL) do |obj| obj.method_1() obj.method_2() end
We only need the define an “apply_dsl” method. The first option is to use simple Ruby blocks to apply the DSL:
class MyClass
def self.apply_dsl(a_class, &block)
yield a_class.new if block_given?
end
end
The second option is to use instance_eval to apply the DSL:
class MyClass
def self.apply_dsl(a_class, &block)
dsl = a_class.new
dsl.instance_eval &block if block_given?
end
end
Or one can use mixins and extend..
class MyClass
def self.apply_dsl(a_module)
obj = MyClass.new
obj.extend(a_module)
obj.init
yield obj if block_given?
end
end
but then one would use modules instead of classes:
module MyDSL
def init
@i = 1
end
def method_1
puts "#{@i}+1=#{@i += 1}"
end
def method_2
puts "says your DSL method"
end
end
[...] we use the block technique mentioned before to apply the DSL in Ruby, we get the following [...]