Skip to content

Instantly share code, notes, and snippets.

@patrickgombert
Last active August 29, 2015 14:04
Show Gist options
  • Save patrickgombert/02ba11fa2e4e24da4aab to your computer and use it in GitHub Desktop.
Save patrickgombert/02ba11fa2e4e24da4aab to your computer and use it in GitHub Desktop.
defmacro defguard({name, _, args}, [do: body]) do
quote bind_quoted: [args: args, body: body, name: name] do
defmacro unquote(name)(unquote_splicing(args)) do
if Macro.Env.in_guard?(__CALLER__) do
quote do
unquote(body)
end
else
eager_bindings = Enum.map args, fn({name, _, _}) ->
{:=, [], [{name, [], nil}, name]}
end
quote bind_quoted: [eager_bindings: eager_bindings, body: body], unquote: true, do: unquote(body)
end
end
end
end
defguard foo(bar), do: bar == "bar"
# => (CompileError) undefined function bar/0
@josevalim
Copy link

defmacro defguard(fun, [do: body]) do
  {name, args} = Macro.decompose_call(fun)
  quote bind_quoted: [args: args, body: body, name: name] do
    defmacro unquote(name)(unquote_splicing(args)) do
      if Macro.Env.in_guard?(__CALLER__) do
        quote do: unquote(body)
      else
        quote bind_quoted: binding, unquote: true, do: unquote(body)
      end
    end
  end
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment