There have been several nice libraries written with modified pipes, but with this one I decided to try and write something that works alongside the default pipe instead of replace it.
Multipipe provides two macros to collect parameters and then apply those parameters using the Elixir pipe. For example:
param(1, %{:a => "ok"})
|> param(2, :a)
|> useparams(Map.get)
The order the parameters are set doesn’t matter, and you can also pipe into the collection:
"a" |> String.to_atom
|> param(2, _)
|> param(1, %{:a => "ok"})
|> useparams(Map.get)
A side effect is that you can pipe into any input:
param(2, :a) |> useparams(Map.get(%{:a => "ok"}))
or
param(1, %{:a => "ok"})
|> param(3, "Key not found.")
|> useparams(Map.get(:a))
The way it’s implemented is that the param
collects the parameters into a map, which useparams
uses to pipe the parameters into the function call.
I’ve also considered making a holdparams
macro that holds the current parameters while another pipeline produces another value. It would work like:
value |> param(1, _)
|> holdparams(stuff)
|> holdparams(morestuff)
|> mergeparams(2)
|> useparams(func)
which would be equivalent to func(value, morestuff(stuff))
. I decided against this because I don’t like the idea of merging so many pipelines into one long one, and didn’t want to encourage that sort of thing.
All suggestions, comments, criticisms, and ideas for improvement welcome. I know the way the macros are written can be improved. I wrestled a while with how they get expanded and doubt I found the best way to deal with it.
https://github.com/johnnyfeng/multipipe
It’s not on hex but I’d be happy to add it if wanted.
edit