Skip to content

Instantly share code, notes, and snippets.

@cjbottaro
Last active January 16, 2016 19:29
Show Gist options
  • Save cjbottaro/5f58808b7f1fd47551c4 to your computer and use it in GitHub Desktop.
Save cjbottaro/5f58808b7f1fd47551c4 to your computer and use it in GitHub Desktop.
Non-hurty, Ruby-like DSL in Elixir
##############
# Define DSL #
##############
defmodule Config.Dsl do
defmacro __using__(_) do
quote do
import unquote(__MODULE__)
@before_compile unquote(__MODULE__)
@processes []
end
end
defmacro __before_compile__(_) do
quote do
# Delete temporary attributes
Module.delete_attribute(__MODULE__, :process)
# Massage some attributes to get intuitive ordering
@processes Enum.reverse(@processes)
def processes do
@processes
end
end
end
defmacro process(name, do: block) do
quote do
@process [name: unquote(name)]
unquote(block)
@processes [ Enum.reverse(@process) | @processes ]
end
end
defmacro start_command(command) do
quote do
@process [ {:start_command, unquote(command)} | @process ]
end
end
defmacro startup(do: block) do
quote do
def startup do
unquote(block)
end
end
end
end
###############
# Use the DSL #
###############
defmodule Config do
use Config.Dsl
@pidfile "/var/run/nginx.pid"
process "nginx" do
start_command "/etc/init.d/nginx start"
end
startup do
IO.puts @pidfile
end
end
###########################
# Result of using the DSL #
###########################
Config.processes |> IO.inspect
# => [[name: "nginx", start_command: "/etc/init.d/nginx start"]]
Config.startup
# => /var/run/nginx.pid
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment