Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to replace Parse::Method::Signatures with Method::Signatures in TryCatch #74

Open
schwern opened this issue Apr 17, 2013 · 0 comments
Labels

Comments

@schwern
Copy link
Contributor

schwern commented Apr 17, 2013

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 }";
    }
  }
@schwern schwern added the API label Mar 26, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant