Skip to content

Instantly share code, notes, and snippets.

@ivan
Created October 22, 2016 19:28
Show Gist options
  • Save ivan/ed9654041989d35a39a39fdf1e3b5e47 to your computer and use it in GitHub Desktop.
Save ivan/ed9654041989d35a39a39fdf1e3b5e47 to your computer and use it in GitHub Desktop.
defmodule LangUtil do
@doc ~S"""
For use in a pipeline like so:
{s, &Kernel.<>/2}
|> oper_if(c.section, "Section: #{c.section}\n")
|> oper_if(true, "Description: #{c.short_description}\n")
|> oper_if(c.long_description, prefix_every_line(c.long_description, " ") <> "\n")
|> elem(0)
`expression` is not evaluated unless evaluation of `clause` is truthy. This avoids
blowing up on nils and other unexpected values.
"""
defmacro oper_if(state, clause, expression) do
quote do
{acc, operator} = unquote(state)
result = if unquote(clause) do
operator.(acc, unquote(expression))
else
acc
end
{result, operator}
end
end
end
defmodule LangUtilTest do
use ExUnit.Case
test "oper_if works on binaries" do
import LangUtil, only: [oper_if: 3]
s = "hello"
out = {s, &Kernel.<>/2}
|> oper_if(true, " ")
|> oper_if(false, "mars")
|> oper_if(true, "world")
|> elem(0)
assert out == "hello world"
end
test "oper_if works on lists" do
import LangUtil, only: [oper_if: 3]
s = ["hello"]
out = {s, &Kernel.++/2}
|> oper_if(true, [" "])
|> oper_if(false, ["mars"])
|> oper_if(true, ["world"])
|> elem(0)
assert out == ["hello", " ", "world"]
end
test "oper_if doesn't evaluate expression unless condition is truthy" do
import LangUtil, only: [oper_if: 3]
s = "hello"
out = {s, &Kernel.<>/2}
|> oper_if(false, "#{:foo + 1}")
|> oper_if(nil, "#{:foo + 2}")
|> elem(0)
assert out == "hello"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment