Input, Output, PIDs, and Nodes

Understand the processing of input and output through functions in nodes.

We'll cover the following

Introduction

Input and output in the Erlang VM are performed using I/O servers. These are simply Erlang processes that implement a low-level message interface. We never have to deal with this interface directly, which is a good thing because it’s complex. Instead, we use the various Elixir and Erlang I/O libraries and let them do the heavy lifting.

Implementation

In Elixir, we identify an open file or device by the PID of its I/O server. And these PIDs behave like all other PIDs. We can, for example, send them between nodes. If we look at the implementation of Elixir’s IO.puts function, we’ll see the following:

def puts(device \\ group_leader(), item) do 
  erl_dev = map_dev(device)
  :io.put_chars erl_dev, [to_iodata(item), ?\n]
end

The default device it uses is returned by the function :erlang.group_leader. (The group_leader function is imported from the :erlang module at the top of the IO module.) This’ll be the PID of an I/O server.

So, we start a terminal, enter a named node and register the PID returned by group_leader under a global name (here, we use :one).

Follow these commands for practice:

$ iex --sname one
iex(one@educative)> :global.register_name(:one, :erlang.group_leader)
:yes
iex(one@educative)> one = :global.whereis_name :one
#PID<0.70.0>
iex(one@educative)> IO.puts(one, "Hello")
Hello
:ok
iex(one@educative)> IO.puts(one, "World!")
World!
:ok

Run the above commands in the terminal below:

Get hands-on with 1400+ tech skills courses.