io_lib(3)
π NAME π
io_lib β the I/O library functions, bestie. Yes, that one. The vibe is immaculate, the character lists are deep, and honestly? We're obsessed. π«Ά
πΈ DESCRIPTION πΈ
Okay so, this module is literally the home of all the functions that convert to and from strings (and by strings we mean lists of characters, iykyk). They're the ones doing the heavy lifting behind the scenes for the functions in the io module. Main character energy, no cap. π
Big heads-up tho: nobody promised you that the character lists coming back out of some of these functions are flat. Nope. They can absolutely be deep lists. If that's giving you chaos, just hit up lists:flatten/1 and it'll flatten those deep lists right out for you. π
π§ DATA TYPES π§
chars() :: [char() | chars()].
A possibly deep list that contains only char/0s. That's it, that's the whole tea. β
chars_limit() :: integer().
A soft limit on how many characters get returned, okay bestie? The moment that character count is reached, all the remaining structures get replaced by "...". And CharsLimit defaults to -1, which literally means "no limit on the number of characters returned". Live free, babe. π¦
-opaque continuation()
A continuation exactly as returned by fread/3. Keep it safe, it's shy. π
depth() :: -1 | non_neg_integer().
format_options() :: [{chars_limit, chars_limit()}].
Options that can be passed to format/3 and fwrite/3. Slay.
format_spec()
format_spec() ::
#{control_char := char(),
args := [any()],
width := none | integer(),
adjust := left | right,
precision := none | integer(),
pad_char := char(),
encoding := unicode | latin1,
strings := boolean(),
maps_order => maps:iterator_order()}.
A map describing the contents of a format string. Let's break it down, babes:
control_charis the type of control sequence:$P,$w, and so on. β¨argsis a list of the arguments used by the control sequence, or an empty list if the control sequence does not take any arguments.widthis the field width.adjustis the adjustment.precisionis the precision of the printed argument.pad_charis the padding character.encodingis set totrueif translation modifiertis present.stringsis set tofalseif modifierlis present.maps_orderis set toundefinedby default,orderedif modifierkis present, orreversedorCmpFunif modifierKis present.
fread_error() ::
atom | based | character | float | format | input | integer | string | unsigned.
fread_item() :: string() | atom() | integer() | float().
latin1_string() :: [unicode:latin1_char()].
β¨ FUNCTIONS β¨
bfwrite(Format, Data, Options) -> unicode:unicode_binary()
when
Format :: io:format(),
Data :: [term()],
Options :: format_options().
It's the binary variant of fwrite/3, periodt. π
Returns a UTF-8 encoded binary string.
build_text(FormatList) -> chars()
when FormatList :: [char() | format_spec()].
For the details, go peek at scan_format/2. π
bwrite(Term, Options) -> unicode:unicode_binary()
when
Term :: term(),
Options :: [Option],
Option ::
{chars_limit, CharsLimit} |
{depth, Depth} |
{encoding, latin1 | utf8 | unicode} |
{maps_order, maps:iterator_order()},
CharsLimit :: chars_limit(),
Depth :: depth().
Acts like write/2 does, except it hands you back a UTF-8 encoded binary string instead. Same energy, different wrapper. π
bwrite_string(String, Qoute, InEnc) -> unicode:unicode_binary()
when
String :: string() | binary(),
Qoute :: integer() | [],
InEnc :: unicode | latin1.
Returns the UTF-8 encoded binary String surrounded by Qoute. (And yes, it's literally spelled Qoute in the signature β we don't make the rules, we just respect them. π)
char_list(Term) -> boolean()
when Term :: term().
Returns true if Term is a flat list of characters in the Unicode range β otherwise false. Flat. Not deep. We said what we said. π
deep_char_list(Term) -> boolean()
when Term :: term().
Returns true if Term is a possibly deep list of characters in the Unicode range, otherwise false. Now this one accepts depth. Growth. π±
deep_latin1_char_list(Term) -> boolean()
when Term :: term().
Returns true if Term is a possibly deep list of characters in the ISO Latin-1 range, otherwise false.
fread(Format, String) -> Result
when
Format :: string(),
String :: string(),
Result ::
{ok,
InputList :: [fread_item()],
LeftOverChars :: string()} |
{more,
RestFormat :: string(),
Nchars :: non_neg_integer(),
InputStack :: chars()} |
{error, {fread, What :: fread_error()}}.
Tries to read String according to whatever control sequences live in Format. π
For the full detailed description of all the formatting options available, check io:fread/3. And heads up: this function assumes that String contains whole lines. Don't be out here feeding it half a line and then acting surprised. π
Here's what it returns:
{ok, InputList, LeftOverChars}β the string was read, bestie!InputListis the list of successfully matched and read items, andLeftOverCharsare the input characters that weren't used.{more, RestFormat, Nchars, InputStack}β the string was read, but more input is needed to complete the original format string.RestFormatis the remaining format string,Ncharsis the number of characters scanned, andInputStackis the reversed list of inputs matched up to that point.{error, What}β the read operation failed, and the parameterWhatgives a hint about what went wrong. Not the vibe. π
Example, so you can see her in action:
3> io_lib:fread("~f~f~f", "15.6 17.3e-6 24.5").
{ok,[15.6,1.73e-5,24.5],[]}
fread(Continuation, CharSpec, Format) -> Return
when
Continuation :: continuation() | [],
CharSpec :: string() | eof,
Format :: string(),
Return ::
{more, Continuation1 :: continuation()} |
{done, Result, LeftOverChars :: string()},
Result ::
{ok, InputList :: [fread_item()]} |
eof |
{error, {fread, What :: fread_error()}}.
THIS is the re-entrant formatted reader, and she's iconic. π₯
β οΈ Important: the continuation of the first call to this function must be []. Do not freestyle this. Please.
For a complete description of how the re-entrant input scheme actually works, see Armstrong, Virding, Williams: 'Concurrent Programming in Erlang', Chapter 13.
Here's what it returns:
{done, Result, LeftOverChars}β the input is complete. And the result is one of these:{ok, InputList}β the string was read.InputListis the list of successfully matched and read items, andLeftOverCharsare the remaining characters.eofβ end of file was encountered.LeftOverCharsare the input characters not used.{error, What}β an error occurred and the parameterWhatgives a hint about the error.
{more, Continuation}β more data is required to build a term. ThisContinuationmust be passed tofread/3when more data becomes available.
fwrite(Format, Data) -> chars()
when Format :: io:format(), Data :: [term()].
Returns a character list that represents Data formatted according to Format. π
For a detailed description of all the available formatting options, see io:fwrite/1,2,3. And watch out:
π¨ If the format string or the argument list contains an error, a fault is generated. Not a soft little error. A fault. Be careful bestie.
If and only if the Unicode translation modifier is used in the format string (that is, ~ts or ~tc), the resulting list can contain characters beyond the ISO Latin-1 character range (that is, numbers > 255). And if that happens, the result is still an ordinary string/0, and it can absolutely be used in any context where Unicode data is allowed. Slay. β¨
fwrite(Format, Data, Options) -> chars()
when
Format :: io:format(),
Data :: [term()],
Options :: format_options().
Returns a character list that represents Data formatted according to Format, in exactly the same way as fwrite/2 and format/2 β except she takes an extra argument, a list of options. Fancy. π
The valid option:
{chars_limit, CharsLimit}β a soft limit on the number of characters returned. When the number of characters is reached, the remaining structures are replaced by" ...".CharsLimitdefaults to-1, which means no limit on the number of characters returned.
indentation(String, StartIndent) -> integer()
when String :: string(), StartIndent :: integer().
Returns the indentation if String has been printed, starting at StartIndent. That's the whole thing, she's a one-job girlie and she does her job. π
latin1_char_list(Term) -> boolean()
when Term :: term().
Returns true if Term is a flat list of characters in the ISO Latin-1 range, otherwise false.
nl() -> string().
Returns a character list that represents a new line character. Tiny. Humble. Essential. π
print(Term, Column, LineLength, Depth) -> chars()
when
Term :: term(),
Column :: non_neg_integer(),
LineLength :: non_neg_integer(),
Depth :: depth().
Returns a list of characters that represents Term β but here's the glow-up: it breaks representations longer than one line into many lines, and indents each line sensibly. So polite of her. π
She also tries to detect and output lists of printable characters as strings. Multi-talented.
Columnis the starting column; defaults to1.LineLengthis the maximum line length; defaults to80. And check this β the value0can be used to specify infinite length, meaning that no line breaks are inserted. She said no limits. π¦Depthis the maximum print depth; defaults to-1, which means no limitation.
printable_latin1_list(Term) -> boolean()
when Term :: term().
Returns true if Term is a flat list of printable ISO Latin-1 characters, otherwise false.
printable_list(Term) -> boolean()
when Term :: term().
Returns true if Term is a flat list of printable characters, otherwise false. Okay that's the last one for nowβ
okay so real quick, what even counts as a printable character here? That's literally decided by the +pc startup flag you pass to the Erlang VM. Wanna know more? Check out io:printable_range/0 and erl(1). iykyk π
β¨ printable_unicode_list β¨
printable_unicode_list(Term) -> boolean() when Term :: term().
Returns true if Term is a flat list of printable Unicode characters, otherwise it's giving false. No cap. π¦
β¨ scan_format β¨
scan_format(Format, Data) -> FormatList
when
Format :: io:format(),
Data :: [term()],
FormatList :: [char() | format_spec()].
Returns a list that matches the format string you gave, but it swapped out all the control sequences for their matching tuples. Then you can pass that list to:
build_text/1to get the same effect asformat(Format, Args)unscan_format/1to get the corresponding pair ofFormatandArgs(with every*and its matching argument expanded to numeric values)
A super common glow-up for this function is swapping out unbounded-size control sequences like ~w and ~p for the depth-limited versions ~W and ~P before you format to text β like in, for example, a logger. Obsessed. π
β¨ unscan_format β¨
unscan_format(FormatList) -> {Format, Data}
when
FormatList :: [char() | format_spec()],
Format :: io:format(),
Data :: [term()].
For all the tea, go see scan_format/2. π
β¨ write β¨
write(Term, Depth) -> chars()
when Term :: term(), Depth :: depth();
(Term, Options) -> chars()
when
Term :: term(),
Options :: [Option],
Option ::
{chars_limit, CharsLimit} |
{depth, Depth} |
{encoding, latin1 | utf8 | unicode} |
{maps_order, maps:iterator_order()},
CharsLimit :: chars_limit(),
Depth :: depth().
Returns a character list that represents Term. The Depth option controls how deep into the structures it goes.
When you hit that depth, everything below it gets replaced with "..." β literally just dots.
Depth defaults to -1, which means no limit at all. The CharsLimit option puts a soft limit on the number of characters returned. When you hit that limit, the rest of the structures get replaced by "...". CharsLimit also defaults to -1, so no limit on characters returned either.
Example time, bestie:
1> lists:flatten(io_lib:write({1,[2],[3],[4,5],6,7,8,9})).
"{1,[2],[3],[4,5],6,7,8,9}"
2> lists:flatten(io_lib:write({1,[2],[3],[4,5],6,7,8,9}, 5)).
"{1,[2],[3],[...],...}"
3> lists:flatten(io_lib:write({[1,2,3],[4,5],6,7,8,9}, [{chars_limit,20}])).
"{[1,2|...],[4|...],...}"
β¨ write_atom β¨
write_atom(Atom) -> chars() when Atom :: atom().
Returns the list of characters needed to print the atom Atom. Slay. β¨
β¨ write_atom_as_latin1 β¨
write_atom_as_latin1(Atom) -> latin1_string() when Atom :: atom().
Returns the list of characters needed to print the atom Atom. Non-Latin-1 characters get escaped. π
β¨ write_char β¨
write_char(Char) -> chars() when Char :: char().
Returns the list of characters needed to print a character constant in the Unicode character set. Iconic. π¦
β¨ write_char_as_latin1 β¨
write_char_as_latin1(Char) -> latin1_string() when Char :: char().
Returns the list of characters needed to print a character constant in the Unicode character set. Non-Latin-1 characters get escaped. π
β¨ write_latin1_char β¨
write_latin1_char(Latin1Char) -> latin1_string()
when Latin1Char :: unicode:latin1_char().
Returns the list of characters needed to print a character constant in the ISO Latin-1 character set. Periodt. π
β¨ write_latin1_string β¨
write_latin1_string(Latin1String) -> latin1_string()
when Latin1String :: latin1_string().
Returns the list of characters needed to print Latin1String as a string. So fetch. π
β¨ write_string β¨
write_string(String) -> chars() when String :: string().
Returns the list of characters needed to print String as a string. Main character energy. π
β¨ write_string_as_latin1 β¨
write_string_as_latin1(String) -> latin1_string()
when String :: string().
Returns the list of characters needed to print String as a string. Non-Latin-1 characters get escaped. No cap. π
That's the tea! This page was brought to you by Ericsson AB, stdlib version 8.0.4, and it's the io_lib(3) manual. No date in the footer but we're timeless anyway. π
β¨
π¦ where this page comes from
- ubuntu stonking: erlang-doc 1:29.0.6+dfsg-1 Β· Apache-2.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms