Skip to content

Instantly share code, notes, and snippets.

@ProGM
Created May 15, 2022 19:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ProGM/291ccc5f7ba50ae359b74f4d60ab2f7d to your computer and use it in GitHub Desktop.
Save ProGM/291ccc5f7ba50ae359b74f4d60ab2f7d to your computer and use it in GitHub Desktop.
DSL Example in Ruby
recipe :pasta do
add 1.liter, of: :water, in: :pot
turn_on :fire
wait_until :pot, :boiling?
add 1.gram, of: :salt, in: :pot
wait 1.minute
add 150.grams, of: :pasta, in: :pot
cook for: 3.minutes
remove :water, from: :pot
eat :pasta
end
class CookbookDSL
def initialize(file_name)
@recipes = []
instance_eval(File.read(file_name), file_name)
end
def recipe(name, &block)
@recipes << Recipe.new(name, &block)
end
end
class Ingredient
def initialize(name, options = {})
@name = name
@options = options
end
end
class Action
def initialize(action, options = {})
@action = action
@options = options
end
end
class Recipe
def initialize(&block)
@steps = []
instance_eval(&block)
end
def add(amount, options)
@steps << Ingredient.new(amount, options)
end
def turn_on(device)
@steps << Action.new(:turn_on, device)
end
def wait(time)
@steps << Action.new(:wait, time)
end
def wait_until(device, condition)
@steps << Action.new(:wait_until, device, condition)
end
def remove(device, options)
@steps << Action.new(:remove, device, options)
end
def cook(options)
@steps << Action.new(:cook, options)
end
def eat(item)
@steps << Action.new(:eat, item)
end
end
class Quantity
def initialize(value, unit_of_measure)
@value = value
@unit_of_measure = unit_of_measure
end
end
class Integer
def grams
Quantity.new(self, :grams)
end
def gram
Quantity.new(self, :grams)
end
def liter
Quantity.new(self, :liters)
end
def liters
Quantity.new(self, :liters)
end
def kilograms
Quantity.new(self * 1000, :grams)
end
end
CookbookDSL.new('./Cookbook')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment