1
votes

I'm unable to write a list to a file in elixir. If I try to write the whole list I get an error, if I try to enumerate over the list I get an error. it's a list of integers.

{:ok, file} = File.open "loop_issues.csv", [:write]
for item <- find_common_items(list_one, list_two) do
  IO.write(file, item <> ",")
end    
File.close file

Here's an example of the IEX readout from the module, and me playing with it.

commons
 [6579, 9397]
** (ArgumentError) argument error
    (autoupgrader_phx) lib/modules/tree_validator.ex:30: anonymous fn/3 in TreeV
alidator.check_all_users/0
              (elixir) lib/enum.ex:1755: Enum."-reduce/3-lists^foldl/2-0-"/3
    (autoupgrader_phx) lib/modules/tree_validator.ex:29: anonymous fn/3 in TreeV
alidator.check_all_users/0
              (elixir) lib/enum.ex:1755: Enum."-reduce/3-lists^foldl/2-0-"/3
    (autoupgrader_phx) lib/modules/tree_validator.ex:14: 

Here's where I was messing with it to test it:

iex(2)> {:ok, file} = File.open "test_file.txt", [:write]
{:ok, #PID<0.469.0>}

iex(3)> whatever = [123, 234, 6324]
[123, 234, 6324]

iex(4)> IO.write(file, whatever)
** (ErlangError) erlang error: :no_translation
    (stdlib) :io.put_chars(#PID<0.469.0>, :unicode, [123, 234, 6324])

And in a loop instead, I also tried Enum.reduce:

iex(4)> for thing <- whatever, do: IO.write(file, thing)
** (ErlangError) erlang error: :terminated
    (stdlib) :io.put_chars(#PID<0.469.0>, :unicode, "123")

What am I doing wrong. I also tried binwrite but that gave the same error.

1

1 Answers

5
votes

IO.write/2 expects an argument to be a chardata | String.Chars.t. Internally it calls Erlang’s :io.put_chars/2.

There is no magic conversion of the list [1] to chardata "[1]", the list is treated as a list of chars and [123, 234] is an invalid unicode sequence. Look:

iex> IO.write(file, [65, 66, 67])
:ok

And what you get in the file is ABC because 65 is the unicode/ascii value for A.

Turning back to how to spit the list of integers out: you should convert the input to something that implements String.Chars protocol:

iex> IO.write(file, inspect(whatever))
:ok

And in the file itself you’ll get:

[123, 234, 6324]