Try::Tiny
Try::Tiny rocks.
Every perl programmer should start using it. Especially if you’re a CPAN module author and wants to eval { } inside your module (often to check if an user of your module has some optional module installed, in which case you optimize stuff for it etc.), you’re strongly suggested to use this module instead of your own eval { } stuff.
Why? If you do eval { } in your module that clobbers the global $@, and to avoid that you need to local $@, and then if you want to die (rethrow) from local $@ then the exception gets cleared etc… Try::Tiny solves this endless yak shaving and there’re no dependencies at all and works with perl back to 5.005x.
Anyway, i started using Try::Tiny (when nothingmuch himself added this :)) in Plack and Tatsumaki with so much fun, but last night I experienced one minor pitfall of this module that I might want to share with you.
I had this code:
sub write {
my $self = shift;
my $writer = $self->writer || $self->init_writer;
$writer->write(@_);
}
I wanted to catch Broken pipe exception from ->write, so I changed to do this:
sub write {
my $self = shift;
my $writer = $self->writer || $self->init_writer;
try {
$writer->write(@_);
} catch {
/Broken pipe/ and $self->{client_disconnected} = 1;
};
}
It might be obvious to you but for me it wasn’t at first, and I wasted about 15 minutes to figure out what’s wrong with that code.
Yeah, the use of @_ in the try { } clause. it’s internally implemented as try sub { … } so the content of @_ is changed when it’s executed.
Lots of clever modules on CPAN that exports DSL sugars (including my own Web::Scraper) shares the same problem. At least you have to be careful not to use @_ in the block, by assigning the @_ content into some lexical variables before you construct the block,
(Well maybe Try::Tiny can add a workaround to save the @_ in the caller stack but i’m not sure if it’s a doable without black magic like DB::args and whether it’s right thing to do anyway)
Anyways, Try::Tiny is a great module if you care about this tiny thing. Enjoy.
UPDATE: this is now mentioned in Try::Tiny POD docs.