DEV Community

Cover image for Loo: Yet Another Way To Introspect Data
LNATION for LNATION

Posted on

Loo: Yet Another Way To Introspect Data

A Side note: I'm currently on look out for a new contract or permanent opportunity. If you know of any relevant openings, I'd appreciate hearing from you. I am a proficient front-end developer also - email@lnation.org

If you've spent any time debugging Perl, you've used Data::Dumper. It's one of those modules that ships with every Perl installation, gets loaded into every debugging session, and does its job without complaint. But it also hasn't changed much in a long time. The output is monochrome, the internals are pure Perl, and code references remain opaque sub { "DUMMY" } blobs unless you enable Deparse and even then you do not get the response one would expect.

Loo is a new take on the same problem: dump Perl data structures to readable output, but do it in C, with colour, and with a built-in code deparser that walks the op tree directly.

Why Another Dumper?

Three reasons drove the creation of Loo:

Speed. Loo is implemented entirely in XS. The dump logic, string escaping, colour code generation, and op tree walking all happen in C. For large or deeply nested structures, this matters.

Colour out of the box. When your terminal supports it, Loo's output is coloured by default. Strings, numbers, hash keys, braces, blessed class names, regex patterns, and code all get distinct colours that can be customised. There's no separate module to install, no formatter to configure. It auto-detects terminal capability, respects $ENV{NO_COLOR}, and falls back to plain text when appropriate.

Code deparsing without B::Deparse. When you pass a code reference to Loo with deparsing enabled, it walks Perl's internal op tree in C and reconstructs the source. This is not a wrapper around B::Deparse — it's a standalone implementation that lives in the same XS compilation unit as the introspecter itself.

Getting Started

Loo provides a functional interface that mirrors Data::Dumper closely enough that switching is straightforward:

use Loo qw(Dump cDump ncDump dDump);

# Colour auto-detected based on terminal
print Dump({ name => 'Perl', version => 5.40 });

# Force colour on (useful when piping to a pager that supports ANSI)
print cDump([1, 2, 3]);

# Force colour off (useful for logging or file output)
print ncDump(\%ENV);

# Dump with code deparsing enabled
print dDump(sub { my ($x) = @_; return $x * 2 });
Enter fullscreen mode Exit fullscreen mode

The OO interface supports method chaining and gives you access to the full set of configuration options:

my $loo = Loo->new([{ key => 'value' }], ['data']);
$loo->Indent(1)->Sortkeys(1)->Theme('monokai');
print $loo->Dump;
Enter fullscreen mode Exit fullscreen mode

Data::Dumper Compatibility

Loo implements the same accessor interface as Data::Dumper: Indent, Terse, Varname, Useqq, Quotekeys, Sortkeys, Maxdepth, Maxrecurse, Purity, Deepcopy, Pair, Freezer, Toaster, Bless, Deparse, Sparseseen, and Pad. If you have existing code that configures a Data::Dumper object, the same method calls work on a Loo object and is faster.

Beyond that, Loo adds a few options that Data::Dumper doesn't have:

  • Indentwidth($n) — control the number of characters per indent level (default 2)
  • Usetabs($bool) — indent with tabs instead of spaces
  • Trailingcomma($bool) — add trailing commas after the last element in arrays and hashes

Colour Customisation

Loo ships with four built-in themes: default, light (optimised for light terminal backgrounds), monokai, and none.

For fine-grained control, the Colour method accepts a hash specifying foreground and background colours for 17 distinct syntax elements:

$loo->Colour({
    string_fg  => 'green',
    key_fg     => 'magenta',
    number_fg  => 'cyan',
    brace_fg   => 'bright_black',
    undef_fg   => 'red',
});
Enter fullscreen mode Exit fullscreen mode

The colorable elements cover every visual component of the output: string, number, key, brace, bracket, paren, arrow, comma, undef, blessed, regex, code, variable, quote, keyword, operator, and comment.

Colour codes are pre-computed once at configuration time, so there's no per-character overhead during the dump.

The Deparser

The most unusual feature of Loo is its built-in code deparser. When you enable deparsing, Loo walks the Perl op tree directly in C — the same internal structure that the Perl interpreter executes — and reconstructs Perl source code from it.

my $loo = Loo->new([\&Some::function]);
$loo->Deparse(1);
print $loo->Dump;
Enter fullscreen mode Exit fullscreen mode

This means code references in your data structures are no longer black boxes. You see the actual code that will be run from the code. NOTE: It may not be identical to the code written as some postfix operations are lost as I am deparsing the compiled op tree itself.

Getting this to work across Perl versions was one of the harder parts of the project. The op tree structure has changed across Perl releases — OP_PADSV_STORE appeared in 5.38, OP_EMPTYAVHV landed in 5.36 as an enum rather than a #define, and PADNAME typedefs shifted between 5.20 and 5.22. Loo handles all of this with version-conditional compilation, supporting Perl 5.10 through to the latest releases.

Reusable C Headers

Loo's XS code is organised into modular C headers:

  • loo.h — core definitions, themes, colour element names
  • loo_colour.h — ANSI colour code generation
  • loo_escape.h — string escaping
  • loo_dump.h — recursive data structure dumping
  • loo_deparse.h — op tree walking and code reconstruction

These headers are installed alongside the Perl module, and Loo->include_dir returns their path. This means other XS modules can reuse Loo's colour or escaping logic without duplicating the C code.

Auto-Detection Done Right

Loo follows the no-color.org convention and layers several checks to decide whether to emit ANSI codes:

  1. If $Loo::USE_COLOUR is set, that takes precedence
  2. If $ENV{NO_COLOR} is set, colour is disabled
  3. If $ENV{TERM} is "dumb", colour is disabled
  4. If STDOUT is not a terminal, colour is disabled
  5. Otherwise, colour is enabled

This means Dump() does the right thing whether you're debugging interactively, piping to a file, or running in CI. And cDump() / ncDump() are there when you need to override.

Installation

Loo is available on CPAN:

cpanm Loo
Enter fullscreen mode Exit fullscreen mode

It requires Perl 5.008003 or later and a C compiler (which you already have if you've ever installed an XS module).

Closing Thoughts

Data::Dumper is a workhorse that has served the Perl community well for decades. Loo isn't trying to replace it everywhere — but if you spend a lot of time reading dump output, colour and deparsing make a real difference. And if you're dumping large structures in production logging or tooling, the XS implementation gives you that output faster.

Give it a look. Your eyes may thank you.

Top comments (0)