Packages

Macros expanding into code that can be safely used in guard clauses.

Current section

Files

Jump to
guardsafe lib guardsafe.ex
Raw

lib/guardsafe.ex

defmodule Guardsafe do
@vsn "0.3.1"
@doc false
def version, do: @vsn
@moduledoc """
Provides readability-enhancing macros that can safely be used in guard clauses.
## Examples
defmodule MacrofyAllTheThings do
import Guardsafe
require Integer
def magic(number) when number |> nil? do
"Staring into the void..."
end
def magic(number) when number |> even? do
"That's not odd."
end
def magic(number) when number |> divisible_by? 5 do
"High five!"
end
end
iex> MacrofyAllTheThings.magic(8)
"That's not odd."
"""
@doc """
Returns true if the integer number is evenly divisible by the divisor.
## Examples
iex> 25 |> divisible_by? 5
true
"""
defmacro divisible_by?(number, divisor) do
quote do
rem(unquote(number), unquote(divisor)) == 0
end
end
@doc """
Returns true for even integers.
## Examples
iex> even? 7
false
"""
defmacro even?(number) do
quote do
divisible_by?(unquote(number), 2)
end
end
@doc """
Returns true for odd integers.
## Examples
iex> odd? 5
true
"""
defmacro odd?(number) do
quote do
not even?(unquote(number))
end
end
require_warning = fn(module) ->
unless module == Kernel, do: "\n\nRemember to `require #{module}` before use."
end
generate_predicates = fn({module, types}) ->
@module String.to_atom "Elixir.#{module}"
types
|> Enum.each fn(type) ->
@predicate String.to_atom("#{type}?")
@function String.to_atom("is_#{type}")
@doc """
Expands `#{@predicate}(term)` into `#{module}.#{@function}(term)`.
#{require_warning.(@module)}
## Examples
iex> some_#{type}_variable |> #{@predicate}
true
"""
defmacro unquote(@predicate)(term) do
quote do
unquote(@module).unquote(@function)(unquote(term))
end
end
end
end
[
Kernel: ~w(atom binary bitstring boolean float function integer list map nil number pid port reference tuple),
]
|> Enum.each generate_predicates
@doc """
Expands `function?(term, arity)` into `is_function(term, arity)`
## Examples
iex> &String.to_integer/1 |> function?(2)
false
"""
defmacro function?(term, arity) do
quote do
is_function(unquote(term), unquote(arity))
end
end
end