pipet v0.1.4 Pipet View Source
Macro for conditionally piping a value through a series of expressions.
Prior art
Pipet was heavily inspired by, and would not exist without:
Link to this section Summary
Functions
Conditionally pipe a value through a series of operations
Link to this section Functions
Conditionally pipe a value through a series of operations.
pipes
is a series of conditional expressions. At each step of the way, if the condition
succeeds, then the value will be applied as the first argument of the last expression of the body
of the condition as in |>
, and if the condition fails the expression will be skipped. The
supported forms of conditional expressions are:
if
unless
cond
case
with
Raw function calls are also supported, in which case the value is piped through just like in |>
Examples
Basic if
conditions are supported:
pipet [1, 2, 3] do
if do_increment?(), do: Enum.map(& &1 + 1)
if do_double?(), do: Enum.map(& &1 * 1)
if do_string?(), do: Enum.map(&to_string/1)
end
case
and cond
use whichever branch succeeds:
pipet [1, 2, 3] do
case operation do
:increment -> Enum.map(& &1 + 1)
:double -> map(& &1 * 1)
:string -> Enum.map(&to_string/1)
end
end
with
pipes through the do
block if all pattern matches succeed, or uses the first successful
else
block if a pattern fails.
pipet [1, 2, 3] do
with {:ok, x} <- get_value() do
Enum.map(& &1 + x)
else
:something_else -> Enum.map(& &1 + 1)
end
end
Conditional expressions can be combined with bare function calls, which will always execute:
pipet ["1", "2", "3"] do
String.to_integer()
if do_increment?(), do: Enum.map(& &1 + 1)
end
Multi-expression bodies pipe through the last expression:
pipet [1, 2, 3] do
if do_add_num?() do
num = 3
Enum.map(& &1 + num)
end
case something() do
{:ok, x} ->
x = x + 1
Enum.map(& &1 + x)
:error ->
Enum.map(& &1 - 2)
end
end
Notes
pipet
evaluates conditions in order, not all at once. For example, the following:def print_hello_and_return_true() do IO.puts “hello” true end
pipet 1 do if print_hello_and_return_true() do
IO.puts "world" increment()
end unless print_hello_and_return_true() do
IO.puts "goodbye"
end end
prints:
hello world hello
the rules for
case
andwith
are as usual - if none of the branches of acase
block or of anelse
block in awith
statement match aCaseClauseError
orWithClauseError
respectively will be thrown. If you want a fallthrough case, you can provide a call to the identity function:pipet 1 do case {:foo, :bar} do
:never_matches -> increment() _ -> (& &1).()
end end
pipet 1 do with {:ok, x} <- :some_tuple do
increment()
else
:doesnt_match -> increment() _ -> (& &1).()
end end