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 http://rvirding.blogspot.com/2008/11/erlang-rationale.html . 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 http://erlang.org/doc/apps/stdlib/io_protocol.html 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: http://ferd.ca/repl-a-bit-more-and-less-than-that.html
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.