IO.puts generates ArgumentError on binary

Hello! I am having an issue where IO.puts on a specific binary is generating an ArgumentError.

iex> IO.puts <<32, 32, 145, 225, 8, 179, 180, 12, 65, 83, 232, 51, 96, 25, 206, 113, 158, 163, 89, 233, 199, 129, 103, 78, 161, 83, 246, 125, 32, 250, 166, 202>>
** (ArgumentError) argument error
    (stdlib 3.16.1) io.erl:99: :io.put_chars(:standard_io, [<<32, 32, 145, 225, 8, 179, 180, 12, 65, 83, 232, 51, 96, 25, 206, 113, 158, 163, 89, 233, 199, 129, 103, 78, 161, 83, 246, 125, 32, 250, 166, 202>>, 10])
iex>

I am posting this in hopes of clarifying and checking my understanding, as I think I now understand why this is happening but am not 100% sure.

My understanding is that in Elixir, values of type String.t() are UTF-8 strings and are also of type binary(), but not necessarily the other way around in that all binary() are not String.t(). For example, you can have a binary which doesn’t represent a UTF-8 string. In Elixir, if a binary value represents a UTF-8 string, it is displayed as so, such as <<75, 90>> being displayed as "KZ".

The input type of IO.puts is chardata | String.Chars.t().

Is the ArgumentError above because the binary data doesn’t represent a UTF-8 string? Is encoding the binary to UTF-16 using Base.encode16/1 a way to always display binaries as string data? What’s the general way one should “print” binary data in Elixir?

Is this right or is there something else going wrong?

Yes.

That isn’t what Base.encode16 does. Base.encode16 encodes a binary as a hexadecimal utf8 string. It will however always return a printable string, no matter what binary you give it.

1 Like

Yea, that’s what I meant. My wording may have been off a bit. I meant to just use Base.encode16/1 as a way to convert any binary to a hexadecimal string.

Thank you for taking a look and confirming this! This was one of those situations where I got confused, typed up a draft, but then did more reading and sort of figured it out, but I wanted a gut check by posting here. Thanks again.

1 Like