Issue
I’m tinkering with learning Elixir coming from a Ruby background. I noticed that when I pipe the result of String.trim() to IO.puts() the string is printed with it’s carriage return intact
token = IO.gets "enter your token" |> String.trim() |> IO.puts()
returns "string123\n"
However, if I do something like this:
token = IO.gets "enter your token" |> String.strip()
IO.puts(token)
The output is then "string123"
Why is my first solution not trimming the carriage return?
Solution
TLDR: It’s a race condition precedence issue. What you get is the result of calling IO.gets/2
that gets completed the last.
Actually, the first line does some weird assignment. IO.puts/2
returns :ok
always, it does not return a string, it spits it out to stdout
. What happens, is (I put the order in which functions get executed):
# 6 1 2 3 4 5
token = IO.gets "enter your token" |> String.trim() |> IO.puts()
# it’s the same as:
token = IO.gets("enter your token" |> String.trim() |> IO.puts())
One might put parentheses around the argument to IO.gets/2
, but this will only shift an issue to another part of code.
token = IO.gets("enter your token") |> String.trim() |> IO.puts()
#⇒ enter your token123
# 123
# :ok
token
#⇒ :ok
So far, String.trim/1
works perfectly. What you need is to just assign the returned result to your token
variable:
token = "enter your token" |> IO.gets() |> String.trim()
Now you get your trimmed value in your token
variable.
Answered By – Aleksei Matiushkin
Answer Checked By – Gilberto Lyons (BugsFixing Admin)