Skip to content

Instantly share code, notes, and snippets.

@alco
Created April 4, 2012 14:13
Show Gist options
  • Save alco/2301410 to your computer and use it in GitHub Desktop.
Save alco/2301410 to your computer and use it in GitHub Desktop.
A handy macro for replacing vars with atoms and vice versa
defmodule Atomize do
@doc """
Given an expression, replaces all variables with atoms and atoms with
variables.
For example,
a = 1; b = "string"
Atomize.invert {a, :a, {{b, :b}, [c, d]}}
#=> {:a, 1, {{:b, "string"}, [:c, :d]}}
It can be useful when passing large amounts of atoms between Elixir and
Erlang.
"""
defmacro invert(expr) do
vars_to_atoms expr
end
defp vars_to_atoms({atom, _, nil}), do: atom
defp vars_to_atoms(atom) when is_atom(atom), do: {atom, 0, nil}
defp vars_to_atoms({atom, _line, args}) when is_list(args) do
{atom, _line, vars_to_atoms(args)}
end
defp vars_to_atoms(tuple) when is_tuple(tuple) do
list_to_tuple(vars_to_atoms tuple_to_list(tuple))
end
defp vars_to_atoms(list) when is_list(list) do
lc arg in list, do: vars_to_atoms(arg)
end
defp vars_to_atoms(other), do: other
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment