Packages

A fun, positional pipe operator macro >>> for when piping to the first arg just won't cut it.

Current section

Files

Jump to
bowfish lib bowfish.ex
Raw

lib/bowfish.ex

defmodule Bowfish do
@moduledoc """
A fun, positional pipe operator, for when the first arg just won't cut it.
Pipes an expr into function args by replacing the first instance of ":_"
"""
@doc ~S"""
Pipes the expr into the reserved position.
## Examples
# a trivial example -> you'd really just use "|>" here
iex> import Bowfish
iex> "bowfish" >>> String.upcase(:_)
"BOWFISH"
# piping to functions
iex> defmodule Test do
iex> def div(a, b), do: a / b
iex> end
iex> import Bowfish
iex> 4 >>> Test.div(1, :_)
0.25
# using with an anonymous function
iex> import Bowfish
iex> add = fn (a, b) -> a + b end
iex> 5 >>> add.(1, :_)
6
# using in a chain
iex> import Bowfish
iex> add = fn (a, b, c) -> a + b + c end
iex> 1 >>> add.(1, 0, :_) >>> Integer.to_string(16, :_)
"10000"
# using with the forward pipe operator
iex> import Bowfish
iex> add = fn (a, b, c) -> a + b + c end
iex> 2
iex> >>> add.(1, :_, 40)
iex> |> Integer.to_string()
iex> |> String.codepoints()
iex> |> Enum.reverse()
iex> >>> Enum.concat(["1","2"], :_)
["1","2","3","4"]
"""
defmacro left >>> right do
bowfish(left, right)
end
def bowfish(expr, {call, line, args}) when is_list(args) do
case Enum.find_index(args, fn x -> x == :_ end) do
nil -> raise ArgumentError, "unable to determine index of ':_'"
idx -> Macro.pipe(expr, {call, line, List.delete_at(args, idx)}, idx)
end
end
def bowfish(_expr, _) do
raise ArgumentError, "cannot pipe to a function that doesn't expect a list of args"
end
end