Setting the length for when ~P wrapps the text in erlang - erlang

Is there a way to make erlang print the full string even if one has used ~P in a io:format function?
Im having some troubles with EDoc and it keeps wrapping the error messages to ....
Is there any flags or other way to force erlang to print the entire string?

The only method I have found is to use io_lib:print(Term, Column, LineLength, Depth). That function allows you to specify the starting column, the line length to control wrapping, etc. It returns a string which you can then print using io:format with ~s format.

Related

Erlang printing hex instead of integer

I have been trying to fix a problem for hours now, very new to erlang
lists:sublist([6,9,15,24,39,6,96],7,1).
I want this to print "100" instead of "d"
what I am i doing wrong here?
The shell is going to try to print strings as strings whenever it would be legal. That means lists of integers that happen to all be valid characters will be printed as characters, and lists that contain other things will be printed as lists:
1> [65,66,67].
"ABC"
2> [3,65,66,67].
[3,65,66,67]
But notice that I did not actually call any output functions. That was just the shell's convenience operation of implicitly echoing whatever a returned value was so you, as a programmer, can inspect it.
If I want to explicitly call an output function I should use a format string that specifies the nature of the values to be interpolated:
3> io:format("This is a list: ~tw~n", [List]).
This is a list: [65,66,67]
ok
4> io:format("This is a list rendered as an implied string: ~tp~n", [List]).
This is a list rendered as an implied string: "ABC"
ok
5> io:format("This is a string: ~ts~n", [List]).
This is a string: ABC
ok
Note the additional atom ok after each print. That is because the return value from io:format/2 is ok. So we are getting the explicit output from format/2 and then seeing its return value.
The io module doc page has the gritty details: http://erlang.org/doc/man/io.html#format-1
Back to your example...
6> lists:sublist([6,9,15,24,39,6,96],7,1).
"`"
7> io:format("~tw~n", [lists:sublist([6,9,15,24,39,6,96],7,1)]).
[96]
ok
Addendum
There is a setting called shell:strings/1 that tells the shell to turn string formatting on and off:
1> [65,66,67].
"ABC"
2> shell:strings(false).
true
3> [65,66,67].
[65,66,67]
4> <<65,66,67>>.
<<65,66,67>>
5> shell:strings(true).
false
6> <<65,66,67>>.
<<"ABC">>
But I don't mess with this setting ever anymore for a few reasons:
It is almost never worth the effort to remember this detail of the shell (convenience output from the shell is mostly useful for discovering return value structures, not specific values held by those structures -- and when you want that data you usually want strings printed as strings anyway).
It can cause surprising shell output in any case where you really are dealing with strings.
This is almost never the behavior you actually want.
When dealing with real programs you will need actual output functions using io or io_lib modules, and developing habits around format strings is much more useful than worrying over convenience output from the shell.

why does io:get_line return "\n" in erlang shell?

when using io:getline("prompt") in the erlang shell , the function returns immediately with a return value of "\n"
io:get_line("prompt").
prompt
"\n"
but as suggested in another thread doing the following reads from standard_io correctly.
spawn(fun() -> timer:sleep(100),io:get_line("prompt") end).
waits for user input and reads from standard io (shell). It was mentioned that it was a race condition . can anyone tell me why is it so and how is it possible to read a value from the erlang shell ?
io:get_line/1 and io:get_line/2 returns data with \n every time.
get_line(Prompt) -> Data | server_no_data()
Where:
Data
The characters in the line terminated by a LF (or end of file). If the
IO device supports Unicode, the data may represent codepoints larger
than 255 (the latin1 range). If the I/O server is set to deliver
binaries, they will be encoded in UTF-8 (regardless of if the IO
device actually supports Unicode or not).
In first case you got \n, and try to get result of io:get_line in second case:
spawn(fun() ->
timer:sleep(100),
Result = io:get_line("prompt"),
io:format("Result: ~p~n", [Result])
end).
Let's break it down...
Why io:get_line/1 returns a \n?
io:get_line/1 returns a "line" and a \n ("end of a line" or "new line") constitutes a line together with the string you entered.
> io:get_line("Prompt:").
Prompt:TheStringIEntered
"TheStringIEntered\n"
How to read a value from the Erlang shell?
> Data = string:strip(io:get_line("Prompt:"), right, $\n).
Prompt:TheStringIEntered
"TheStringIEntered"
> Data.
"TheStringIEntered"
Note that the value (Data) here is always of string type. You can convert it into other types, but you always start with a string.
Why does spawn(fun() -> timer:sleep(100),io:get_line("prompt") end). behave differently?
Because spawn spawns a new process that temporarily takes over the shell. Once this process gets TheStringIEntered, it also reaches the end of its life. So it dies without having its return value (TheStringIEntered) printed to the shell.

reading file whole flat text file to an array

Im working with erlang writing an escript and Ive seen many examples with file io, not so easy to follow so i found this:
Text = file:read_file("f.txt"),
io:format("~n", Text).
works somehow, it does print the file contents followed by multiple errors
in call from erl_eval:do_apply/6 (erl_eval.erl, line 572)
in call from escript:eval_exprs/5 (escript.erl, line 850)
in call from erl_eval:local_func/5 (erl_eval.erl, line 470)
in call from escript:interpret/4 (escript.erl, line 768)
in call from escript:start/1 (escript.erl, line 277)
in call from init:start_it/1 (init.erl, line 1050)
in call from init:start_em/1 (init.erl, line 1030)
so what would be the easiest way to read the whole file and store the contents in an array or list for later use?
First, file:read_file/1 will return {ok, Binary} on success, where Binary is a binary representing the contents of the file. On error, {error, Reason} is returned. Thus your Text variable is actually a tuple. The easy fix (crashing if there is an error):
{ok, Text} = file:read_file("f.txt")
Next, the first argument to io:format/2 is a format string. ~n is a format that means "newline", but you haven't given it a format that means anything else, so it's not expecting Text as an argument. Furthermore, all arguments to the format string should be in a list passed as the second argument. ~s means string, so:
io:format("~s~n", [Text])
will print out the entire file, followed by a newline. If you want to pass multiple arguments, it would look something like:
io:format("The number ~B and the string ~s~n", [100, "hello"])
Notice how there are only two arguments to io:format/2; one just happens to be a list containing multiple entries.
Since your question asked for an easy way to read the contents of a file into a data-structure, you might enjoy file:consult/1. This solution assumes, you have control over the format of the file since consult/1 expects the file to consist of lines terminated with '.'. It returns {ok, [terms()]} | {error,Reason}.
So, if your file, t.txt, consisted of lines terminated by '.' as follows:
'this is an atom'.
{person, "john", "smith"}.
[1,2,3].
then you could utilize file:consult/1
1> file:consult("c:\t.txt").
2> {ok,['this is an atom',{person,"john","smith"},[1,2,3]]}

Erlang - io:format 's result / (formatting with io_lib:format/2)

I'm trying to get the result of the output of io:format/1.
I know that there's a similar function in io_lib, io_lib:format/2, but the output is different. In fact, it doesn't do anything at all.
If I try to bound io:format, ok is bounded, and the formatted string is written out to the console.
So my question is, how can I get the same output with io_lib:format/2?
Or how can I bound the formatted string to a variable?
1> A = io:get_line('> ').
> "test".
"\"test\".\n"
2> io:format(A).
"test".
ok
3> B = io_lib:format(A, []).
"\"test\".\n"
4> B.
"\"test\".\n"
5> C = io:format(A).
"test".
ok
6> C.
ok
io_lib:format is not an output function the way io:format is. Instead io_lib:format only returns the value, but does not output it.
The result of io:format that you see as "test." is the rendered version as sent to the terminal (including the newline) , then it returns ok. Conversely, the return value of io_lib:format that you see as "\"test\".\n" is simply the erlang shell's representation of the same string, with the quotes and newline escaped, and surrounded by its own quotes.
io_lib:format is more commonly used for inserting values into the strings (similar to C's printf functions). For example, doing something like
NewString = io_lib:format("The string entered was ~s I hope you like it",[A])
The value of NewString would be
The string entered was "test".
I hope you like it
For which the Erlang Shell's representation would be:
"The string entered was \"test\".\n I hope you like it"
If all you want to do is output the value you just entered, then io:format is sufficient for your needs.

Can I disable printing lists of small integers as strings in Erlang shell?

The Erlang shell "guesses" whether a given list is a printable string and prints it that way for convenience. Can this "convenience" be disabled?
I don't know if it's possible to change the default behavior of the shell, but you can at least format your output correctly, using io:format.
Here is an example:
1> io:format("~p~n", [[65, 66, 67]]).
"ABC"
ok
2> io:format("~w~n", [[65, 66, 67]]).
[65,66,67]
ok
And since the shell is only for experimenting / maintenance, io:format() should be at least enough for your real application. Maybe you should also consider to write your own format/print method, e.g. formatPerson() or something like that, which formats everything nicely.
You can disable such behavior with shell:strings/1 function starting with Erlang R16B.
Just remember that this is option global to all node shells, and it might be wise to set it back after finishing playing is shell in longer living nodes.
I tend to do it by prepending an atom to my list in the shell.
for example:
Eshell V5.7.4 (abort with ^G)
1> [65,66,67].
"ABC"
2> [a|[65,66,67]].
[a,65,66,67]
could also be [a,65,66,67], of course. but [a|fun_that_returns_a_list()] will print "the right thing(ish) most of the time"
As of Erlang/OTP R16B, you can use the function shell:strings/1 to turn this on or off. Note that it also affects printing of things that are actually meant to be strings, such as "foo" in the following example:
1> {[8,9,10], "foo"}.
{"\b\t\n","foo"}
2> shell:strings(false).
true
3> {[8,9,10], "foo"}.
{[8,9,10],[102,111,111]}
No, there is no way to disable it. The best alternative I find is to either explicitly print out the value in the query (with io:format) or after the fact do: io:format("~w\n", [v(-1)]).
I don't think you can prevent it.
Prepending an atom seems like a kludge - it does alter your original string.
I typically use lists:flatten(String) to force it to a string - especially the returnvalue of io_lib:format() does not always print as a string. Using lists:flatten() on it makes it one.
I use the following "C-style":
sprintf(Format) ->
sprintf(Format, []).
sprintf(Format, Args) ->
lists:flatten(io_lib:format(Format, Args)).
The problem is that the string is not a type in Erlang. A string is just a list of integers, so there's no way for the shell to distinguish a printable string from a generic list. Don't know if this answer to your question.

Resources