Skip to content

Instantly share code, notes, and snippets.

@ms-ati
Last active February 8, 2019 08:42
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ms-ati/2bb17bdf10a430faba98 to your computer and use it in GitHub Desktop.
Save ms-ati/2bb17bdf10a430faba98 to your computer and use it in GitHub Desktop.
Example of a recursive multi-level DSL in Ruby using Docile gem
require 'docile'
# Family tree node, mother and father are Person values as well
Person = Struct.new(:name, :mother, :father)
# Recursive dsl in a mutating builder using Docile
def person(&block)
Docile.dsl_eval(PersonBuilder.new, &block).build
end
# Notice how the builder uses `person` to recurse
class PersonBuilder
def initialize
@p = Person.new
end
def name(v)
@p.name = v
end
def mother(&block)
@p.mother = person(&block)
end
def father(&block)
@p.father = person(&block)
end
def build
@p
end
end
# Example DSL usage
p = person {
name 'John Smith'
mother {
name 'Mary Smith'
}
father {
name 'Tom Smith'
mother {
name 'Jane Smith'
}
}
}
puts p
# Output from this example
#
#=> #<struct Person name="John Smith",
# mother=#<struct Person name="Mary Smith", mother=nil, father=nil>,
# father=#<struct Person name="Tom Smith",
# mother=#<struct Person name="Jane Smith", mother=nil, father=nil>,
# father=nil>>
#
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment