TEST2::MANUAL::TOOLING::FORMATTER(3perl)

πŸ’– NAME πŸ’–

Test2::Manual::Tooling::Formatter β€” bestie, this is literally the tutorial on how to write your own custom formatter. And in this case, we're building a JSONL formatter, so slay.

(Also it lives in the Perl Programmers Reference Guide, iykyk πŸ’…)


✨ DESCRIPTION ✨

Okay so this tutorial walks you through a minimal formatter that dumps every event as a json string, one per line. That's it. That's the whole vibe. 🌸

A real formatter is gonna be way more complicated than this, no cap β€” but this gives you the basics you need to get started. Think of it as the starter pack. πŸŽ€


🧚 COMPLETE CODE UP FRONT 🧚

Here's the whole thing, no cliffhangers, we're not gatekeeping:

package Test2::Formatter::MyFormatter;
use strict;
use warnings;

use JSON::MaybeXS qw/encode_json/;

use base qw/Test2::Formatter/;

sub new { bless {}, shift }

sub encoding {};

sub write {
    my ($self, $e, $num, $f) = @_;
    $f ||= $e->facet_data;

    print encode_json($f), "\n";
}

1;

Iconic. Obsessed. Now let's go line by line because the details matter fr fr. πŸ’…


🌈 LINE BY LINE 🌈

  • use base qw/Test2::Formatter/; β€” Every single formatter ever should inherit from Test2::Formatter. That's the rule, periodt.
  • sub new { bless {}, shift } β€” Formatters need to be instantiable objects, so here's a tiny lil new() method, minimal but functional.
  • sub encoding {}; β€” For this example we just leave this sub empty. In general though? You should implement this sub so you honor the situations where the encoding is set. Fun fact: Test2::V0 itself will try to set the encoding to UTF8.
  • sub write { ... } β€” The write() method is the most important one β€” this is where every event gets sent. Main character sub, honestly. πŸ‘‘

Inside write() we've got this:

my ($self, $e, $num, $f) = @_;

The write() method receives 3 or 4 arguments β€” that fourth one is optional, bestie.

  • $self β€” The formatter itself. Hi, that's you. πŸ‘‹
  • $e β€” The event being written.
  • $num β€” The most recent assertion number. If the event being processed is an assertion, then this has been bumped by 1 since the last call to write. For non-assertions, this number is set to the most recent assertion.
  • $f β€” This MAY be a hashref containing all the facet data from the event. But more often than not it'll be undefined. It's only set if the facet data was needed by the hub, and usually... it just isn't. πŸ™ˆ

Then:

$f ||= $e->facet_data;

We want to dump the event facet data, so this sets $f to the facet data β€” unless we already have it, in which case we're good. Efficiency, queen. ✨

And finally:

print encode_json($f), "\n";

This line prints the JSON encoded facet data, plus a newline. That's it, that's the whole formatter doing its thing. πŸ¦‹


Lowkey important reminder: this is a minimal example. Your real formatter will probably be doing way more than this, and that's totally fine.

πŸ’œ SEE ALSO πŸ’œ

  • Test2::Manual β€” The primary index of the manual. Go there if you want the whole map, bestie. πŸ—ΊοΈ

πŸ”₯ SOURCE πŸ”₯

The source code repository for Test2-Manual can be found at:

https://github.com/Test-More/test-more/

Go star it or whatever, support the ecosystem. ⭐


πŸ‘‘ MAINTAINERS πŸ‘‘

  • Chad Granum <exodist@cpan.org>

🌸 AUTHORS 🌸

  • Chad Granum <exodist@cpan.org>

Copyright Chad Granum <exodist@cpan.org>.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

See:

http://dev.perl.org/licenses/

And that's a wrap, bestie! 🫢 This was perl v5.44.0, dated 2026-10-17 β€” go forth and format some events, you absolute icon. πŸ’–βœ¨

πŸ“¦ where this page comes from
  • arch rolling: perl 5.44.0-1 Β· Artistic-1.0-Perl AND GPL-1.0-or-later
  • πŸ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms