Pretty v1.0.5 Pretty View Source
Inspect values with syntax colors despite your remote console.
This module addresses two surprises you'll encounter trying to dump data to the remote console
like you did during development with iex -S mix
:
IO.inspect/1
et al work fine at theiex>
prompt but somehow not when called from a:telemetry
handler function or other troubleshooting mechanism... unless you think to look at the log outputThe syntax colors aren't working like you think they should, either
The inspection width is 80... just like
iex
, now that you think of it
Why? See the explanation.
In case of emergency, BREAK GLASS (see below) to get what you need with some copying and pasting.
Usage
To get the right syntax colors and inspection width, replace your calls to IO.inspect/1
with
calls to Pretty.inspect/1
:
Pretty.inspect(<<0, 1, 2>>, width: 40)
... and IO.inspect/2
with Pretty.inspect/2
:
[1, 2, 3]
|> Pretty.inspect(label: "before")
|> Enum.map(&(&1 * 2))
|> Pretty.inspect(label: "after")
|> Enum.sum()
To get the right colors, width, and output device, use Pretty.bind/1
to get an inspector/1
function, and use it instead of IO.inspect/1
or Pretty.inspect/1
:
dump = Pretty.bind(label: "Ecto")
handler = fn name, m10s, m6a, nil -> dump.({name, m10s, m6a}) end
:telemetry.attach(self(), [:my_app, :repo, :query], handler, nil)
BREAK GLASS
If you're sitting at a remote console right now and just need some output without taking a new
dependency and re-releasing, paste this in to get most of the functionality of Pretty.bind/1
right away:
bind = fn opts ->
device = Process.group_leader()
width = with {:ok, n} <- :io.columns(device), do: n, else: (_ -> %Inspect.Opts{}.width)
opts = Keyword.merge(:rpc.call(:erlang.node(device), IEx.Config, :inspect_opts, []), opts)
opts = Keyword.merge(opts, pretty: true, width: width)
reset = Enum.find_value(Keyword.get(opts, :syntax_colors, []), [], fn _ -> IO.ANSI.reset() end)
fn term -> IO.puts(device, [Kernel.inspect(term, opts), reset]); term end
end
# I never said it'd be Pretty...
# Can you make it shorter? PR or it didn't happen.
... and then use that:
dump = bind.(label: "ecto")
handler = fn name, m10s, m6a, nil -> dump.({name, m10s, m6a}) end
:telemetry.attach(self(), [:my_app, :repo, :query], handler, nil)
What's going on? See the explanation.
Link to this section Summary
Types
Keyword options supported by IO.inspect/2
.
A 1-ary inspection function returning its argument unchanged e.g. IO.inspect/1
.
Functions
Bind an inspection function to the current standard output.
Bind an inspection function to a particular device.
Inspect an item, writing the report to the standard output. Return the item unchanged.
Inspect an item, writing the report to a device. Return the item unchanged.
Link to this section Types
Specs
inspect_opts() :: keyword()
Keyword options supported by IO.inspect/2
.
Specs
inspector(item) :: (item -> item)
A 1-ary inspection function returning its argument unchanged e.g. IO.inspect/1
.
Link to this section Functions
Specs
bind(inspect_opts()) :: inspector(any())
Bind an inspection function to the current standard output.
See bind/2
for more details.
Specs
bind(IO.device(), inspect_opts()) :: inspector(any())
Bind an inspection function to a particular device.
The inspector's device and options are resolved when bind/2
is called, not when the inspector
is called. If you bind at the remote console prompt, the device and options will remain
appropriate for your console no matter which process calls the inspector.
See inspect/3
for details on option handling.
Specs
inspect(item, inspect_opts()) :: item when item: var
Inspect an item, writing the report to the standard output. Return the item unchanged.
Like IO.inspect/2
, but with pretty defaults appropriate to the device.
See inspect/3
for details on option handling.
Specs
inspect(IO.device(), item, inspect_opts()) :: item when item: var
Inspect an item, writing the report to a device. Return the item unchanged.
Like IO.inspect/3
, but with pretty defaults appropriate to the device
:
- Set
pretty
totrue
- Set
width
according to the device's:io.columns/1
if possible, else theInspect.Opts
default of 80 - Set
syntax_colors
according to the device node'sIEx.Config.inspect_opts/1