439748 (2) [Avatar] Offline
#1
Hi,

This is my solution for the practice exercise 3.4.5

def large_lines!(path) do
File.stream!(path)
|> Stream.map(&String.replace(&1,"\n",""))
|> Enum.map(&String.length(&1))
end

And the result is: 'n\nn'

I checked the solution and it has the same result.

if I added a couple of lines to the text file and I get the expected result with my code and the solution code: [110, 10, 110, 1, 2, 3].

Is this the default behavior or do I need to do something else to get always a list?

Thanks,
sjuric (85) [Avatar] Offline
#2
I assume you expect the result [110, 10, 110]. The thing is that you in fact do get that result. However, a list of integers will be displayed as the character string (aka Erlang string) if all of its elements are ASCII codes representing printable characters. This is briefly mentioned in the book at the end of page 46 (PDF page 71).

You can easily verify this in iex:

iex(1)> [110, 10, 110]
'n\nn'


And you can also check that both values are the same thing:

iex(2)> [110, 10, 110] == 'n\nn'
true


If there is a non-printable character in the list, then a list of integer is displayed. This is the reason why you see integers if you add a couple of short lines, since 1, 2, and 3 don't correspond to printable characters.

If you're using inspect or IO.inspect to display your results, you can explicitly disable this conversion:

iex(1)> IO.inspect([110, 10, 110], charlists: :as_lists)
[110, 10, 110]
'n\nn'


In the snippet above, [110, 10, 110] is the output printed by IO.inspect, while 'n\nn' is the result of the function, which is still converted by the shell into a charlist.

You can also prevent iex from converting expression results into a charlist using IEx.configure:

iex(1)> IEx.configure(inspect: [charlists: :as_lists])
:ok

iex(2)> [110, 10, 110]
[110, 10, 110]


However, in this case Erlang strings are also going to be printed as list of integers:

iex(3)> 'a character list'
[97, 32, 99, 104, 97, 114, 97, 99, 116, 101, 114, 32, 108, 105, 115, 116]

439748 (2) [Avatar] Offline
#3
Thanks for the answer, it was really helpful.

100% recommended book.

I thought that I could have issues looping through it, but no, it is just the representation as you mentioned on your answer.

Streams.large_lines!("test1.txt") |> Enum.each(&IO.puts(&1) )
110
10
110
:ok

Thanks again.