Configure IEx to Show Lists as Lists
Charlists are a holdover from Erlang as an alternate form of string. In Erlang, strings are syntax sugar on a list of binary characters that make up that string. In Elixir, strings are syntax sugar over UTF-8 encoded binaries.Erlang also has the concept of binaries (called a bitstring), they just aren’t the default string implementation. Elixir chose to implement strings directly on top of bitstrings instead of lists. Since Elixir has first class support for Erlang code, it needs to easy to convert Elixir strings into the charlists that Erlang functions expect.If you’re interested in reading more, here is a note about charlists in Elixir’s documentation.
Elixir’s support for charlists manifests in interesting ways. By default, Elixir’s IEx renders lists that contain printable characters as charlists.
Thus:
iex()> Enum.chunk_every(1..10, 2)
[[1, 2], [3, 4], [5, 6], '\a\b', '\t\n']
The single-quoted '
characters on the right are charlists. However, it’s a bit annoying to have to translate between charlists and the actual lists. In this case: [7, 8]
and [9, 10]
that those charlists represent.
The pretty printing that IEx does when it returns a value is powered by Elixir’s inspect
. inspect
takes some configuration, as detailed in Inspect.Opts
Read the rest of the options available here.:infer
is why our example above is partially charlists, it only recognises the list starting with 7
to be entirely printable characters and opportunistically transforms it.:
:charlists
- when:as_charlists
all lists will be printed as charlists, non-printable elements will be escaped. When:as_lists
all lists will be printed as lists.When the default
:infer
, the list will be printed as a charlist if it is printable, otherwise as list. SeeList.ascii_printable?/1
to learn when a charlist is printable.
Kernel.inspect/2
accepts a list of options that are internally translated to an Inspect.Opts
struct:
iex()> inspect(Enum.chunk_every(1..10, 2), charlists: :as_lists)
"[[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]"
Now I have a string that looks correct, but I would like IEx to return the value, but print it correctly. And I would like to not have to invoke inspect
with my settings every time.
Thankfully, IEx gives us IEx.configure
that allow me to configure my IEx session. IEx.configure
takes a keyword list of options to set, and offers inspect
as a possible key:
iex()> IEx.configure(inspect: [charlists: :as_lists])
:ok
iex()> Enum.chunk_every(1..10, 2)
[[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]
Success!
If I want to make this happen every time, I can add the IEx.configure
call to ~/.iex.exs
.You can set things on a per-project basis too, read more here.