How to Write Guard Macros
June 10, 2015
elixir
I recently discovered that it is possible to write custom guard macros for Elixir, provided that the macro expands to expressions that are supported in guards natively.
I used this to create an is_blank
guard. Elixir doesn’t come with a blank?
function, so you have to do it manually. Blank values are " "
, ""
, and nil
. To check blank?
in Elixir, you can check if a given value is in
this array of blank values.
value in [" ", "", nil] # => true / false
You can do this in a guard:
def foo(bar) when bar in [" ", "", nil] do
# baz ...
end
Using in
directly works great if you only have to do it once. But if you find yourself wanting is_blank
all over your code, you can write a macro like so:
defmacro is_blank(value) do
quote do
unquote(value) in [" ", "", nil]
end
end
You can then use is_blank
in your guard statement, because the in
clause is supported by guards natively:
def foo(bar) when is_blank(bar) do
# baz ...
end
You can also use is_blank
like any other function in other parts of your code, outside of guards.
Gotchas
Macros used in guards must be defined in a different module than the one where they are being used. This is due to the way Elixir compiles macros.
You must
require
orimport
your other module in order to be able to use the Macro. If yourequire
, you’ll have to use the macro like this:OtherModule.macro
. If you useimport
, you can just usemacro
.