[SOLVED] Carriage return not being trimmed when piping to String.trim

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)

Leave a Reply

Your email address will not be published. Required fields are marked *