Las funciones para manejar la entrada y la salida las proporciona el módulo IO.
IO.puts/2 escribe un string en la salida estándar, seguido de un salto de línea. Devuelve :ok.IO.write/2 escribe un string en la salida estándar, sin agregar un salto de línea. Devuelve :ok.IO.gets/2 lee una línea de la entrada estándar.IO.inspect/2 escribe cualquier cosa en la salida estándar y acepta opciones útiles como :label. Devuelve sin cambios el valor que recibió. Es útil para depurar.String.Chars
Si intentas pasarle a IO.puts/2 un valor que no puede imprimir, verás un error Protocol.UndefinedError.
IO.puts({:ok, 7})
# ** (Protocol.UndefinedError) protocol String.Chars not implemented for {:ok, 7} of type Tuple
Cuando esto ocurra, quizá quieras usar IO.inspect/2 en su lugar.
IO.inspect/2 para depurarIO.inspect/2 es perfecto para depurar porque devuelve su argumento sin cambios, puede imprimir cualquier cosa y ofrece una opción :label.
"HELLO\n"
|> String.trim()
|> IO.inspect(label: "step 1")
|> String.downcase()
|> IO.inspect(label: "step 2")
# > step 1: "HELLO"
# > step 2: "hello"
# => "hello"
El primer argumento de todas esas funciones es un dispositivo de IO, cuyo valor predeterminado es :stdio (entrada/salida estándar). Para escribir en el dispositivo de error estándar, usa :stderr en su lugar. Un dispositivo de IO también puede ser un proceso, por ejemplo uno creado al llamar a File.open/2, lo que permitiría escribir en un archivo.