ConditionSystem
view release on metacpan or search on metacpan
lib/ConditionSystem.pm view on Meta::CPAN
package ConditionSystem;
BEGIN {
$ConditionSystem::VERSION = '0.02';
}
# ABSTRACT: A Common Lisp like condition/restart system for exceptions
use strict;
use warnings FATAL => 'all';
use Scope::Upper qw( unwind :words );
use Scalar::Util 'blessed';
use Try::Tiny;
use Sub::Exporter -setup => {
exports => [qw( restart with_handlers bind_continue handle restart_case )],
groups => {
default => [qw( restart with_handlers bind_continue handle restart_case )]
}
};
our %handlers;
our %cases;
BEGIN {
no strict 'refs';
*{'CORE::GLOBAL::die'} = sub {
my $err = shift;
for my $handles (keys %handlers) {
if($err->isa($handles)) {
my $handler = $handlers{$handles};
$handler = ${$handler}
if blessed($handler) && $handler->isa('Try::Tiny::Catch');
unwind $handler->($err) => UP UP HERE;
return "Well, it should never get here...";
}
}
};
};
sub with_handlers (&@) {
my ($code, %handles) = @_;
%handlers = %handles; # XXX Should push onto each handler as a queue
my @ret = $code->();
%handlers = ();
return @ret;
}
sub continue_with (&) {
my @vals = @_;
return sub { @vals }
}
sub restart {
my $name = shift;
my @args = @_;
return sub {
$cases{$name}->(@args)
};
}
sub restart_case (&@) {
my $error = shift->();
%cases = @_;
die $error;
}
# Nom. Sugarz
sub handle {
my ($handles, $code) = @_;
return $handles => $code;
}
sub bind_continue {
my ($restart, $code) = @_;
return $restart => $code;
}
1;
__END__
=pod
=encoding utf-8
=head1 NAME
( run in 1.220 second using v1.01-cache-2.11-cpan-39bf76dae61 )