Ability to replace Parse::Method::Signatures with Method::Signatures in TryCatch
Opened this issue · 0 comments
schwern commented
This is a use case for #64, the signature introspection API.
TryCatch takes an appalling 420ms just to load (by comparison Moose only takes 250ms) on my not at all slow laptop. TryCatch is a great module and this renders it useless to me.
Most of the cost is Parse::Method::Signatures which it uses to add types to its catch blocks. Pretty clever.
Type checking of the exception can be performed by specifing a type
constraint or where clauses in the signature as follows:
catch (TypeFoo $e) { ... }
catch (Dict[code => Int, message => Str] $err) { ... }
As shown in the above example, complex Moose types can be used,
including MooseX::Types style of type constraints
In addition to type checking via Moose type constraints, you can also
use where clauses to only match a certain sub-condition on an error.
For example, assuming that "HTTPError" is a suitably defined TC:
catch (HTTPError $e where { $_->code >= 400 && $_->code <= 499 } ) {
return "4XX error";
}
catch (HTTPError $e) {
return "other http code";
}
Note it's the same syntax we have.
Here is the code in TryCatch which it uses to introspect the catch parameter just like a subroutine parameter would.
my $sig = Parse::Method::Signatures->new(
input => $proto,
from_namespace => $self->get_curstash_name,
type_constraint_callback => \&_string_to_tc,
);
my $errctx = $sig->ppi;
my $param = $sig->param;
$sig->error( $errctx, "Parameter expected")
unless $param;
my $left = $sig->remaining_input;
my $var_code = '';
if (my $var_name = $param->can('variable_name') ) {
my $name = $param->$var_name();
$var_code = "my $name = \$TryCatch::Error;";
}
# (TC $var)
if ($param->has_type_constraints) {
my $tc = $param->meta_type_constraint;
$TryCatch::TC_LIBRARY->{"$tc"} = $tc;
push @conditions, "TryCatch->check_tc('$tc')";
}
# ($var where { $_ } )
if ($param->has_constraints) {
foreach my $con (@{$param->constraints}) {
$con =~ s/^{|}$//g;
push @conditions, "do {local \$_ = \$TryCatch::Error; $con }";
}
}