Elixir return values

Viewed 263

I'm trying to use the pipe operator (|>) to pass values from one function to another, but the results of the first function return my output and ":ok", which then effects the input of the followup |> input.

Example:

defmodule TestPipe do 
def parse(msg), do: IO.puts "Parsed: #{msg}"
end 


iex> "this is my message" |> Test.parse |> Test.parse
iex> Parsed: this is my message
iex> Parsed: ok
iex> :ok
2 Answers

Unfortunately, IO.puts/2 is subtly confusing: although it does print the variable you send it, it actually returns an :ok. This means it's going to be weird to look at its output.

IO.inspect/2 might be more what you're after because it not only prints the output, it returns the input unchanged, making it handy for inspecting pipelines.

Compare it to your example:

defmodule TestPipe do
  def parse(msg), do: IO.inspect(msg, label: "Parsed")
end


iex> "this is my message" |> TestPipe.parse() |> TestPipe.parse()
Parsed: "this is my message"
Parsed: "this is my message"
"this is my message"

As Roger mentioned in another answer, the takeaway is that whenever you're dealing with pipes, you have to be extra-aware of the return values -- in particular watch out when a function returns its value wrapped in a tuple because it may not be what the next function expected.

You need to pattern match here; something like this

{:ok, parse} = TestPipe.parse(msg)

After this, the parse variable will have the result you want, and then you can pipe it to something else:

parse |> some_func() |> some_func()
Related