Created
March 30, 2012 16:33
-
-
Save alco/2252662 to your computer and use it in GitHub Desktop.
A handy `with` macro
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule With do | |
@doc """ | |
Provides a shortcut for multiple function invocations on the same module. | |
Example: | |
x = [1,2,3,4] | |
with List do | |
@append [x, @reverse x] | |
end | |
# => [1,2,3,4,4,3,2,1] | |
# Without `with` macro we would have to write | |
x = [1,2,3,4] | |
List.append [x, List.reverse x] | |
""" | |
defmacro with(ref, do_block) do | |
block = Orddict.get do_block, :do | |
replace_at(block, ref) | |
end | |
defp replace_at({ :@, line, [{fun, _, fun_args}] }, ref) do | |
{{:".", line, [ref, fun]}, line, replace_at(fun_args, ref)} | |
end | |
defp replace_at(tuple, ref) when is_tuple(tuple) do | |
list_to_tuple(replace_at(tuple_to_list(tuple), ref)) | |
end | |
defp replace_at(list, ref) when is_list(list) do | |
lc item in list, do: replace_at(item, ref) | |
end | |
defp replace_at(other, _) do | |
other | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment