Ninigi

Ninigi

Is there a way to inspect a list of integers without accidentally ending up with a charlist?

Story

skip this if you are not interested in the Why

Today I was working on a rewrite of a feature, heavily relying on a 3rd Party HTTP API response, no tests available yet, so I decided to bite the bullet and do what I felt like I had to do. Fortunately all the API connections are done in a way, so at least parts of the return values can be mocked, and no actual request has to be made, but you need to provide a valid response.
The response in this case happened to be a big map - 140+x lines of code after parsing the JSON response and running it through the Elixir Formatter. So I thought I was clever, and ran a real example, writing the response to a txt file, and using File.write!(path, inspect(response), so I could copy-paste a real response into a fixture. The problem was that one part %{..., something_ids: Enum.map(raw["something"], & &1["id"]), ... returned [123], which everyone intuitively knows equals to '{' when inspected, because ?{ == [123].
I was running into weird bugs, because '{' was passed down to an ecto query, which would of course find nothing with those ids, and I was banging my head against the wall, why the hell the changeset error was “invalid association” (a lot more going on behind the scenes, but you get the idea). So, I put IEx.pry into multiple places, and saw the error in the fixture. I did not think much about it, replaced it with the value I knew it should be and… It still did not work.
Of course I put IO.inspect(something_ids) in multiple places and always got '{'. At that time I was already stressed out, because that was NOT the bug I was hunting, this was something in my test setup!

After some more head-banging-against-the-wall, I pasted a screen recording into our developer chat, asking what’s going on, and only 1 minute later someone said "does this explain anything? ?{ #=> [123], and I was very ready to bang my head even more, this time voluntarily, for being such an idiot.

Problem

I think I have a basic understanding of why a list of integers might be displayed as a string, but it gave us problems debugging multiple time now - in fact the guy who gave me the clue, was someone I had given the same clue a few months ago.
Not only debugging tends to get harder, if your outputs are displayed differently than what you would expect, but also admin UIs: I frequently use inspect in interfaces, for example to display exq failed jobs and the arguments, error message etc.

Question

I understand this might be a problem with internal representations, but is there any way to display a list of integers (that could, or could not) be a list of characters?

Sidenote

The universe decided to give me a headache with this, because incidentally, the original bug had the same error message.

Marked As Solved

nathanl

nathanl

Take a look at Inspect.Opts and the :charlists option.

[123, 124] |> IO.inspect(charlists: :as_charlists) # => '{|'
[123, 124] |> IO.inspect(charlists: :as_lists) # => [123, 124]
[123, 124] |> IO.inspect(charlists: :infer) # => '{|'

When the default :infer , the list will be printed as a charlist if it is printable, otherwise as list. See List.ascii_printable?/1 to learn when a charlist is printable.

Also Liked

NobbZ

NobbZ

You can pipe into everything… And the nice thing about IO.inspect is, its an identity function. It will return exactly what you gave it. Together with the :label option, its ideal to do ad-hoc debugging of pipelines:

1
|> IO.inspect(label: "before")
|> Kernel.+(1)
|> IO.inspect(label: "after")
NobbZ

NobbZ

You shouldn’t use IEx.i/1 from within code…

NobbZ

NobbZ

Why should I?

I use IEx.i/1 from iex, while I use IO.inspect/2 from within my code.

NobbZ

NobbZ

i/1 is a helper in iex, it describes the data it sees and prints this description into the terminal, and nothing else. And because some magic in iex its return value is omitted.

Though by doing exactly that, piping the result of i/1 into IO.inspect I’ve learned that it returns :"do not show this result in output".

Where Next?

Popular in Questions Top

sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
yawaramin
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 record...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
pgiesin
This should be a simple problem but I just can’t seem to figure it out. I have a standalone Elixir app that won’t find the database. Dep...
New
tduccuong
Hi, is there any work on GUI with Elixir, that is similar to Electron/Javascript? My idea is to bundle Phoenix and BEAM into a single se...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
dokuzbir
Hello, I am trying to convert my lists to string without losing brackets.For start i have 3 map. They look like these buyer = %{ id: ...
New
polypush135
As many of you may have realized by now (sorry for all the posts here) I’ve been working on a db problem where I’m trying to aggregate a ...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New

Other popular topics Top

JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1140 51847 244
New
William
I would like to know that is there any online source for learning Phoenix Framework for building E-Commerce Store? Any advantage on build...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
AstonJ
You’re a programmer, so you don’t need spoon feeding with the conventional drivel about “this is an integer.” No. You need to know what’s...
New
malloryerik
Hi, this is for people who, like me, have had some friction using .html.heex templates in VSCode. The solution seems to be, in a hyphena...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod -- where is this set? Thanks.
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New

We're in Beta

About us Mission Statement