ETOOBUSY 🚀 minimal blogging for the impatient
En guarde! Playing with Guard
TL;DR
Playing a bit with Guard.
With a little help from wrapperl (Wrapperl, from the past) and a newly compiled perl-5.38.0 (thanks to perl-builder), I got to play with a lot of new shiny toys!
As a matter of fact, I was taking a look at Guard, with two programs that do what I expected them to.
The first is about function scope_guard
, which I suppose is what’s needed
most of the times:
#!/usr/bin/env wrapperl
use v5.38;
use warnings;
use Guard;
$|++;
scoped(shift // 'die');
sub scoped ($what) {
scope_guard(\&en_guarde);
if ($what eq 'die') {
die "whatever!";
}
elsif ($what eq 'return') {
say 'about to return...';
return;
}
elsif ($what eq 'exit') {
say 'exiting...';
exit 1;
}
else {
say 'dumpiiiing!';
CORE::dump();
}
}
sub en_guarde { warn "en_guarde(@_)!" }
This prints:
$ ./guard-1.pl die
whatever! at ./guard-1.pl line 13.
en_guarde()! at ./guard-1.pl line 29.
$ ./guard-1.pl return
about to return...
en_guarde()! at ./guard-1.pl line 29.
$ ./guard-1.pl exit
exiting...
en_guarde()! at ./guard-1.pl line 29.
$ ./guard-1.pl dump
dumpiiiing!
Aborted
Yes, I tried to dump
and it indeed dump
ed right on the post, no
questions asked! So there’s a way, after all, and it does not imply
cutting the power cord!
Sometimes we just need some more control, like well yes this guard is useful but what if I need to complete some stuff in the upper sub? or what if I change my mind and want to commit instead of rolling back?
Well, guard
gets you covered with generating an object whose lifetime
dictates the behaviour, including the possibility to cancel
. The lifetime
thing frees us from the specific lexical scope where the object is generated
and allows us to pass it up in the call chain:
#!/usr/bin/env wrapperl
use v5.38;
use warnings;
use Guard;
$|++;
scope_object();
say '';
say 'we will exit the process now';
sub scope_object {
say 'getting a scope object from a sub, void context';
get_scope_object();
say 'see? en_guarde() was triggered out of the box';
say '';
say 'getting a scope object from a sub, scalar context (collecting it)';
my $object = get_scope_object();
say 'got a scope object from a sub, now returning...';
return;
}
sub get_scope_object { guard(\&en_guarde) }
sub en_guarde { warn "en_guarde(@_)!" }
This prints:
$ ./guard-2.pl
getting a scope object from a sub, void context
en_guarde()! at ./guard-2.pl line 25.
see? en_guarde() was triggered out of the box
getting a scope object from a sub, scalar context (collecting it)
got a scope object from a sub, now returning...
en_guarde()! at ./guard-2.pl line 25.
we will exit the process now
I guess it’s all for today!