Skip to content

Instantly share code, notes, and snippets.

@Wigny
Created June 15, 2023 16:22
Show Gist options
  • Save Wigny/313db79f7ed899be9da404cd8cd2983c to your computer and use it in GitHub Desktop.
Save Wigny/313db79f7ed899be9da404cd8cd2983c to your computer and use it in GitHub Desktop.
defmodule DefBang do
defmacro def!(call, do: block) do
quote bind_quoted: [call: Macro.escape(call, unquote: true), block: Macro.escape(block)], location: :keep do
{name, args} = Macro.decompose_call(call)
def unquote(name)(unquote_splicing(args)) do
unquote(block)
end
def unquote(:"#{name}!")(unquote_splicing(args)) do
case unquote(name)(unquote_splicing(args)) do
{:ok, result} -> result
{:error, error} -> raise error
end
end
end
end
end
defmodule Test do
import DefBang
@doc """
Declares a function and it's bang version.
## Examples
iex> Test.foo("bar")
{:ok, "bar"}
iex> Test.foo("baz")
{:error, "baz"}
iex> Test.foo!("baz")
** (RuntimeError) baz
"""
def! foo("bar"), do: {:ok, "bar"}
def! foo("baz"), do: {:error, "baz"}
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment