How to pass an anonymous function to the pipe in Elixir

Solution 1:

It will look bit weird but must work:

def boundary do
  :crypto.rand_bytes(8)
  |> Base.encode16
  |> (&("--------FormDataBoundary" <> &1)).()
end

Solution 2:

Related: if the "anonymous" function has been assigned to a variable, you can pipe to it like this:

def boundary do
  add_marker = fn (s) ->
    "--------FormDataBoundary" <> s
  end

  :crypto.rand_bytes(8)
  |> Base.encode16
  |> add_marker.()
end

Solution 3:

The accepted answer works, but you can do this a bit more elegantly by using

(&"--------FormDataBoundary#{&1}").()

instead of

(&("--------FormDataBoundary" <> &1)).()

Here is the full function:

def boundary do
  :crypto.strong_rand_bytes(8)
  |> Base.encode16()
  |> (&"--------FormDataBoundary#{&1}").()
end

Bonus: I've also replaced :crypto.rand_bytes/1 (which doesn't exist in elixir 1.6+) with :crypto.strong_rand_bytes/1.

Solution 4:

You can also use something like this:

def boundary do
  :crypto.rand_bytes(8)
  |> Base.encode16
  |> (fn chars -> "--------FormDataBoundary" <> chars end).()
end

One advantage of this form over others is that you can easily write simple 'case' statements:

def do_some_stuff do
  something
  |> a_named_function()
  |> (
    fn
      {:ok, something} -> something
      {:error, something_else} ->
        Logger.error "Error"
        # ...
    end
  ).()
end

From:

  • Anonymous functions in pipe chain · Elixir Recipes

Using fn as above is a tiny bit clearer than couchemar's answer:

def boundary do
  :crypto.rand_bytes(8)
  |> Base.encode16
  |> (&("--------FormDataBoundary" <> &1)).()
end

... but, for your particular example, the above form using & is probably best. If the pipeline expression was more complicated, naming the anonymous function parameters might be more useful.

My answer is also a little more concise than Nathan Long's answer:

def boundary do
  add_marker = fn (s) ->
    "--------FormDataBoundary" <> s
  end

  :crypto.rand_bytes(8)
  |> Base.encode16
  |> add_marker.()
end

... tho his answer would be nicer if, for some reason, you needed to call that function more than once in the pipeline.