X::Tiny(3)

πŸ“¦
version 0.22 Β· 3 versions
, in fedora 43

πŸ’– X::Tiny πŸ’–

okay bestie, gather round, because this is X::Tiny β€” the manual page for it, and it's a base class for a bare-bones exception factory. That's the NAME section, and yes I said it with my whole chest. πŸŽ€

It's giving "small but mighty" and I'm obsessed.


✨ SYNOPSIS ✨

here's the vibe, copied exactly because code is sacred:

package My::Module::X;

use parent qw( X::Tiny );

#----------------------------------------------------------------------

package My::Module::X::Base;

use parent qw( X::Tiny::Base );

#----------------------------------------------------------------------

package My::Module::X::IO;

use parent qw( My::Module::X::Base );

#----------------------------------------------------------------------

package My::Module::X::Blah;

use parent qw( My::Module::X::Base );

sub _new {
    my ($class, @args) = @_;

    my $self = $class->SUPER::_new('Blah blah', @args);

    return bless $self, $class;
}

#----------------------------------------------------------------------

package main;

local $@;   #always!
eval {
    die My::Module::X->create('IO', 'The message', key1 => val1, … );
};

if ( my $err = $@ ) {
    print $err->get('key1');
}

die My::Module::X->create('Blah', key1 => val1, … );

like… look at it. clean. minimal. no drama. πŸ’…


🌸 DESCRIPTION 🌸

so basically: this is a stripped-down exception framework. it hands you a baseline of functionality for distributions that wanna expose exception hierarchies with, and I quote, minimal fuss. it's a pattern the author implemented in some other distributions he made and he was NOT about to copy/paste that around like a clown. fair. iconic behavior honestly. 🫢


πŸ”₯ BENEFITS OF EXCEPTIONS πŸ”₯

okay this is the part where we get a little philosophical but stay with me.

Exceptions are better for error reporting in Perl than the C-style "return in failure" pattern. In brief β€” that's the author's words, and he's right β€” you should use exceptions because they are a logical, natural way to report failures: if you're given a set of instructions, and something goes wrong in one of those instructions, it makes sense to stop and go back to see what to do in response to the problem. like, obviously. periodt.

Perl's built-ins unwisely make the caller responsible for error checking β€” and as a result of that, much Perl code fails to check for failures from those built-ins. which makes for far more difficult debugging when some code down the line just mysteriously produces an unexpected result. 😭 the more sensible pattern is for an exception to be thrown at the spot where the error occurred. main character energy: the error announces itself, in place, immediately.

Perl's default exceptions are just scalars. A more useful pattern is to throw exception objects whose type and attributes can facilitate meaningful error checking. for example β€” you may not care if a call to unlink() fails with "ENOENT", so you can just ignore that failure. Or, you might care, but you might prefer just to warn() rather than to stop what you're doing. see? nuanced. we love range. πŸ’…

X::Tiny is one of many CPAN modules that facilitates this pattern. What separates X::Tiny from other such modules is its light weight: the only "heavy" dependency is overload, which is (in the author's experience) a reasonable trade-off for the helpfulness of having stack traces on uncaught exceptions. and lowkey the best part: (The stack trace is custom logic, much lighter than Carp.) 🧚


πŸ¦‹ FEATURES πŸ¦‹

  • Super-lightweight: No exceptions are loaded until they're needed.
  • Simple, flexible API
  • String overload with stack trace
  • Minimal code necessary

that's the whole list and honestly? no notes. it ate. πŸ”₯


πŸ’œ USAGE πŸ’œ

step one bestie: you'll first create a factory class that subclasses X::Tiny. (In the SYNOPSIS's example, this module is My::Module::X.) All of your exceptions must exist under that factory class's namespace. non-negotiable, that's just the rules. ✨

step two: you'll then create a base exception class for your distribution. In the SYNOPSIS's example, this module is My::Module::X::Base. Your distribution's other exceptions should all subclass this one. everyone in the family tree, together. 🌸


πŸ‘‘ METHODS πŸ‘‘

There's only one method in the factory class. one. single. method. queen behavior.

πŸ’« CLASS->create( TYPE, ARG1, ARG2, .. ) πŸ’«

To create an exception, call the create() method of your factory class. This will load the exception class if it's not already in memory. The TYPE you pass in is equivalent to the exception class's module name but with the factory class's name chopped off the left part. So, if you call:

My::Module::X->create('BadInput', 'foo', 'bar')

… this will instantiate and return an instance of My::Module::X::BadInput, with the arguments "foo" and "bar". slay. that's it, that's the whole trick. πŸŽ€


🌈 EXCEPTION OBJECTS 🌈

See X::Tiny::Base for more information about the features that that module exposes to subclasses. go read it, it's right there, I believe in you. 🫢


πŸ’€ DESIGN CONSIDERATIONS πŸ’€

Admittedly, the lazy-loading behavior here embodies a generally-unwise practice of doing failure-prone work (i.e., loading a module at runtime) in the process of reporting a failure. 😬 yes, we're all aware. In the author's own experience, though, that's a reasonable tradeoff for the expressiveness of typed exceptions.

⚠️ Do be sure that any failure-prone work you do as part of exception instantiation has its own failure-checking mechanism. There really are not meant to be "sub-failures" here! 🚨 like fr fr, do not let your error handler error out.

πŸ“ REPOSITORY πŸ“

<https://github.com/FGasper/p5-X-Tiny>

go star it, bestie. it's free. ⭐


πŸ’– AUTHOR πŸ’–

Felipe Gasper (FELIPE)


Copyright 2017-2019 by Gasper Software Consulting <http://gaspersoftware.com>


🌸 LICENSE 🌸

This distribution is released under the same license as Perl.


and that's the whole page, bestie! this one's from perl v5.42.0, dated 2025-07-25 β€” so like, freshly stamped and everything. now go throw some typed exceptions and text me when it works. πŸ’…βœ¨πŸ¦‹πŸ’œ

πŸ“¦ where this page comes from