Reputation: 23091
In chains of pipes in Elixir, it's standard to place the pipe at the beginning on the line:
1
|> IO.inspect(label: "initial value")
|> Kernel.+(1)
|> IO.inspect(label: "plus one")
|> Kernel.*(2)
|> IO.inspect(label: "times two")
|> Integer.to_string(2)
|> IO.inspect(label: "in binary")
However, when I try to do this in IEx, the following happens:
iex(1)> 1
1
iex(2)> |> IO.inspect(label: "initial value")
** (SyntaxError) iex:2:1: syntax error before: '|>'
It is possible to workaround by moving the pipe operator to the end of the line:
iex(1)> 1 |>
...(1)> IO.inspect(label: "initial value") |>
...(1)> Kernel.+(1) |>
...(1)> IO.inspect(label: "plus one") |>
...(1)> Kernel.*(2) |>
...(1)> IO.inspect(label: "times two") |>
...(1)> Integer.to_string(2) |>
...(1)> IO.inspect(label: "in binary")
initial value: 1
plus one: 2
times two: 4
in binary: "100"
"100"
But that's tedious and unidiomatic. Is it possible to use pipes in IEx with the pipe on the next line, like we do in source files?
Upvotes: 4
Views: 1050
Reputation: 23091
This is supported in recent versions:
Interactive Elixir (1.12.0) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> [1, [2], 3]
[1, [2], 3]
iex(2)> |> List.flatten()
[1, 2, 3]
Prior to Elixir 1.12, it was not possible to copy-paste multi-line pipes like your example verbatim into IEx. This was a symptom of the fact that code in IEx is evaluated line-by-line.
The simplest workaround is to wrap the expression in parentheses:
iex(1)> (
...(1)> 1
...(1)> |> IO.inspect(label: "initial value")
...(1)> |> Kernel.+(1)
...(1)> |> IO.inspect(label: "plus one")
...(1)> |> Kernel.*(2)
...(1)> |> IO.inspect(label: "times two")
...(1)> |> Integer.to_string(2)
...(1)> |> IO.inspect(label: "in binary")
...(1)> )
initial value: 1
plus one: 2
times two: 4
in binary: "100"
"100"
You can also escape the newlines:
iex(1)> 1 \
...(1)> |> IO.inspect(label: "initial value") \
...(1)> |> Kernel.+(1) \
...(1)> |> IO.inspect(label: "plus one") \
...(1)> |> Kernel.*(2) \
...(1)> |> IO.inspect(label: "times two") \
...(1)> |> Integer.to_string(2) \
...(1)> |> IO.inspect(label: "in binary") \
...(1)>
initial value: 1
plus one: 2
times two: 4
in binary: "100"
"100"
Upvotes: 7