A.IO (Aja v0.5.1) View Source

Some extra helper functions for working with IO data, that are not in the core IO module.

Link to this section Summary

Functions

Checks if IO data is empty in "constant" time.

Converts the argument to IO data according to the String.Chars protocol.

Link to this section Functions

Specs

iodata_empty?(iodata()) :: boolean()

Checks if IO data is empty in "constant" time.

Should only need to loop until it finds one character or binary to stop, unlike IO.iodata_length(iodata) == 0 which needs to perform the complete loop to compute the length first.

Examples

iex> A.IO.iodata_empty?(["", []])
true
iex> A.IO.iodata_empty?('a')
false
iex> A.IO.iodata_empty?(["a"])
false
iex> A.IO.iodata_empty?(["", [], ["" | "c"]])
false

Rationale

Even if IO.iodata_length/1 is a very efficient BIF implemented in C, it has a linear algorithmic complexity and can become slow if invoked on an IO list with many elements.

This is not a far-fetched scenario, and a production use case can easily include "big" IO-lists with:

  • JSON encoding to IO-data of long lists / nested objects
  • loops within HTML templates

Specs

to_iodata(String.Chars.t() | iodata() | IO.chardata()) ::
  iodata() | IO.chardata()

Converts the argument to IO data according to the String.Chars protocol.

Leaves lists untouched without any validation, calls to_string/1 on everything else.

This is the function invoked in string interpolations within the i sigil.

Works with both IO data and Chardata, depending on the type of the data parameter.

Examples

iex> A.IO.to_iodata(:foo)
"foo"
iex> A.IO.to_iodata(99)
"99"
iex> A.IO.to_iodata(["abc", 'def' | "ghi"])
["abc", 'def' | "ghi"]