Inside IEx when I run Process.whereis(:standard_error) I got the PID, but not when I run Process.whereis(:standard_io) . Who knows why should this happen and how to get the PID from : stdio ?
That is because the i/o system and the error handling behave in different ways. For the error handling there is a central server process registered under the name :standard_error but this is not case for the i/o system. The best way to view an erlang/elixir system to think OS with many tasks and each one has its own i/o system.
You will find a description of this in the link in the erlang rationale I wrote many years ago Robert on anything: The Erlang Rationale . Towards the end it describes the i/o system and the “task” structure in erlang. You actually hit when you do a ^G in the shell.
Strangely enough this was the first time much of the rationale for erlang was actually described, about 10-15 years after it was designed. This was because we had so thought about it and discussed it we felt it was self-evident that this was the way it should be done. We found out later that not everyone thought the same way, some had not grasped the beauty of our design. ![]()
In The Erlang I/O Protocol — OTP 29.0.2 (stdlib 8.0.1) you will find a description of the i/o-protocol as it is today.
Lol, a lot of mathematical equations may be self-evidently beautiful, but that doesn’t mean everyone understands it. ![]()
/me grumbles about pi being the wrong value…
That’s a great response for a simple question Robert, thank you so much.
Just went through the erlang rationale document and I wish there was more where that came from! Thank you very much for sharing this
@rvirding it’s possible to do something similar to this but with :stdio?
Process.unregister(:standard_error)
{:ok, dev} = StringIO.open("")
Process.register(dev, :standard_error)
Code.eval_file(exercise, File.cwd!) |> elem(0)
captured = StringIO.flush(dev)
Process.unregister(:standard_error)
Process.register(original_stderr, :standard_error)
to capture :stdio output in a variable?
Not directly that I know of. Stdio doesn’t work through a registered process but uses the default process group leader. This is where it goes when you read/write without giving an i/o device.
To exemplify @rvirding’s reply, :standard_io translates to Process.group_leader, which can change per process. :standard_error is a local process though. Here is an interesting post on the different things that are done with the group leader: REPL? A bit more (and less) than that
Fred’s blog gives a very good description of how it looks and why it looks like that. We had OS inspired thinking behind the design of the system. That’s why I like to say that Erlang is not a language with concurrency but a OS with a language. Elixir buys straight into this though iex is not quite as concurrent as the Erlang shell.


















