2

I came across some very strange behavior when mapping Integer.parse over a map of strings in Elixir. I executed the following: Enum.map(["7", "8", "9"], &elem(Integer.parse(&1), 0)) Which resulted in the following output: '\a\b\t'.

Oddly enough if I change the "7" it behaves as I would expect:

`Enum.map(["4", "8", "9"], &elem(Integer.parse(&1), 0))`

Results in [4, 8, 9]

Further experimentation shows that there is similar behavior for every leading number greater than 6 but less than 14

For example Enum.map(["11", "8", "10"], &elem(Integer.parse(&1), 0)) results in '\v\b\n' but Enum.map(["16", "8", "10"], &elem(Integer.parse(&1), 0)) results in [16, 8, 10]

Any explanation for this?

Travis Smith
  • 61
  • 1
  • 6

2 Answers2

4

The problem is that Erlang treats integer lists that in which all elements map to printable ascii characters as charlists. Thus if an integer list is contains only numbers that can be mapped to ascii characters then it will be printed as a sequence of character. [7, 8, 9] == '\a\b\t' returns true as Erlang does not distinguish between the integer list and the charlist version. Whenever the integer list did not produce only printable ASCII the behavior of printing an integer list as with [16, 8, 9] was seen.

Executing i [7, 8, 9] results in an explanation of this behavior.

Travis Smith
  • 61
  • 1
  • 6
0

Basically this is the behaviour that everything that's "printable" it's printed by default as charlist (string with single quotes).

Some folks usually added 0 at the end of the list to get rid of it, but now there's a better solution:

inspect [7, 8, 9], charlists: :as_lists
# "[7, 8, 9]"
inspect [7, 8, 9], charlists: :as_charlists
"'\\a\\b\\t'"

You can read more about customizing display with inspect/2 using h Inspect.Opts.

PatNowak
  • 5,721
  • 1
  • 25
  • 31