si dovrebbe usare IO.inspect
invece di IO.puts
per stampare la rappresentazione interna di un valore:
iex> IO.puts [1, 2]
^A^B # prints "^A^B"
:ok # return value of IO.puts
iex> IO.inspect [1, 2]
[1, 2] # prints "[1, 2]"
[1, 2] # return value of IO.inspect
Tuttavia si potrebbe comunque ottenere problemi con alcuni valori speciali :
iex> IO.inspect [97, 98]
'ab' # prints "'ab'"
'ab' # return value of IO.inspect
Per spiegare questo comportamento, è necessario capire come funzionano le stringhe in elisir. Ci sono due tipi di stringhe. Stringhe binarie (doppie virgolette) e liste di caratteri (quotate singole). Internamente, sono costruiti da primitive più semplici. stringhe binarie sono costruiti da binari, e le liste dei personaggi sono costruiti sulla base di liste:
iex> "ab" # a binary string
"ab"
iex> <<97, 98>> # the same string in binary syntax
"ab"
iex> 'ab' # a character list
'ab'
iex> [97, 98] # the same character list in list syntax
'ab'
Potrebbe sembrare confuso in un primo momento, ma questo accade a causa di due cose. Innanzitutto, non esiste un tipo di stringa incorporato, poiché le stringhe sono state create da altri tipi primitivi. Secondo, non ci sono tipi definiti dall'utente in elisir. Quindi, quando Elixir vede una lista con solo numeri interi, prova a stamparla come stringa per comodità. Tuttavia, sotto il cofano è ancora solo una lista di numeri interi.
Negli esempi sopra, 97
e 98
rappresentano i punti di codice unicode per i caratteri a
e b
così questi verranno visualizzati come una stringa, anche se si utilizza IO.inspect
.
Ora si può vedere perché stampato ^A^B
nei tuoi esempi - questi sono solo control characters from the ASCII encoding, che capita di essere rappresentato dalle codepoints 1
e 2
.
Tuttavia, è possibile passare l'opzione char_lists: :as_lists
al fine di stampare gli elenchi prime, senza un tentativo di fare una conversione:
iex> IO.inspect [97, 98], char_lists: :as_lists
[97, 98] # prints '[97, 98]'
'ab' # Iex still shows the return value as 'ab'
Se aprite iex
e digita h Inspect.Opts
, si vedrà che Elixir fa questo tipo di cosa con altri valori, in particolare struct e binari.
È un grosso errore ritenere che, poiché l'elisir ha l'aspetto di Ruby, si comporterà anche come Ruby. –