Strang difference when calling IO.puts in a function inside File.open (depending on device)

Hi there

it is either and probably just me being stupid (label as bug and wontfix :wink:) or just maybe it’s a bug in Elixir

iex(21)> filen
"/home/robert/tmp/file1"
iex(22)> File.open(filen, [:write], fn f -> IO.puts(f, ["hello", [" ", ["world"]]]) end)
{:ok, :ok}
iex(23)> File.read! filen
"hello world\n"

looks good to me, however

iex(24)> File.open(:stdio, [:write], fn f -> IO.puts(f, ["hello", [" ", ["world"]]]) end)
** (FunctionClauseError) no function clause matching in IO.chardata_to_string/1

    The following arguments were given to IO.chardata_to_string/1:

        # 1
        :stdio

    Attempted function clauses (showing 2 out of 2):

        def chardata_to_string(string) when is_binary(string)
        def chardata_to_string(list) when is_list(list)

    (elixir 1.10.3) lib/io.ex:572: IO.chardata_to_string/1
    (elixir 1.10.3) lib/file.ex:1381: File.open/2
    (elixir 1.10.3) lib/file.ex:1414: File.open/3

Could be normal although slightly unpratical behavior, however:

iex(24)> IO.puts(:stdio, ["hello", [" ", ["world"]]])
hello world
:ok

And yes, I forgot

Erlang/OTP 23 [erts-11.0.1] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]

Interactive Elixir (1.10.4) - press Ctrl+C to exit (type h() ENTER for help)

So what did just happen in iex(24)?

Help’s appreciated

KR
Robert

reproduced with strings instead of chardata BTW

The issue is that File.open expects a Path.t() as first argument and you are passing in an atom.

2 Likes

I would need a reminder of RTF, thank’s a lot, how can I have missed that? Oh please be polite and consider this a rethorical question.

Thx for your quick response

Now would it not be great if File.open(:stdio) returned :stdio though?

(Quite an enormous amount of work I guess)

Well never mind, what I really forgot is that File is not IO :cry:

That wouldn’t be consistent. File.open/2 returns an io_device which is in fact a pid you can use with the functions from the IO module (except in raw mode). :stdio is a shortcut in the IO module which maps to the group leader’s pid. It has no meaning in the context of the File module.

Having pids representing io_devices means that in a distributed setting you can do things such as have a node write to a file that is on another node transparently.

Yeah I realised that, I should not post before thinking, and that’s why I do not post, normally, what about
test driven posting?

Thx for your time again