]> git.vpit.fr Git - perl/modules/Sub-Prototype-Util.git/blobdiff - lib/Sub/Prototype/Util.pm
Fix some croak backtraces
[perl/modules/Sub-Prototype-Util.git] / lib / Sub / Prototype / Util.pm
index 91520b823361f417e9d715e1d3f7f63d4888a04e..20525ece0971b354170d655b1ce89b344100467c 100644 (file)
@@ -57,6 +57,12 @@ sub _check_ref {
  return $r;
 }
 
+sub _clean_msg {
+ my ($msg) = @_;
+ $msg =~ s/(?:\s+called)?\s+at\s+.*$//s;
+ return $msg;
+}
+
 =head2 C<flatten $proto, @args>
 
 Flattens the array C<@args> according to the prototype C<$proto>. When C<@args> is what C<@_> is after calling a subroutine with prototype C<$proto>, C<flatten> returns the list of what C<@_> would have been if there were no prototype.
@@ -72,19 +78,23 @@ sub flatten {
   if ($1) {
    my $a = shift;
    my $r = _check_ref $a, $p;
-   my %deref = (
-    SCALAR => sub { push @args, $$a },
-    ARRAY  => sub { push @args, @$a },
-    HASH   => sub { push @args, %$a },
-    GLOB   => sub { push @args, *$a },
-    CODE   => sub { push @args, &$a }
-   );
-   $deref{$r}->();
+   push @args, $r eq 'SCALAR'
+               ? $$a
+               : ($r eq 'ARRAY'
+                  ? @$a
+                  : ($r eq 'HASH'
+                     ? %$a
+                     : ($r eq 'GLOB'
+                        ? *$a
+                        : &$a # _check_ref ensures this must be a code ref
+                       )
+                    )
+                 );
   } elsif ($p =~ /[\@\%]/) {
    push @args, @_;
    last;
-  } elsif ($p eq '_' && @_ == 0) {
-   push @args, $_;
+  } elsif ($p eq '_') {
+   shift; # without prototype, this argument wouldn't have been passed
   } else {
    push @args, shift;
   }
@@ -135,9 +145,8 @@ For example, this allows you to recall into C<CORE::grep> and C<CORE::map> by us
 
 sub _wrap {
  my ($name, $proto, $i, $args, $cr, $opts) = @_;
if ($proto =~ /(\\?)(\[[^\]]+\]|[^\];])(.*)/g) {
while ($proto =~ s/(\\?)(\[[^\]]+\]|[^\];])//) {
   my ($ref, $p) = ($1, $2);
-  $proto = $3;
   $p = $1 if $p =~ /^\[([^\]]+)\]/;
   my $cur = '$_[' . $i . ']';
   if ($ref) {
@@ -172,11 +181,10 @@ sub _wrap {
   } else {
    $args .= $cur . ', ';
   }
-  return _wrap($name, $proto, ($i + 1), $args, $cr, $opts);
- } else {
-  $args =~ s/,\s*$//;
-  return $name . '(' . $args . ')';
+  ++$i;
  }
+ $args =~ s/,\s*$//;
+ return $name . '(' . $args . ')';
 }
 
 sub _check_name {
@@ -221,7 +229,7 @@ sub wrap {
  $call = 'sub ' . $call if $opts{sub};
  if ($opts{compile}) {
   $call = eval $call;
-  croak $@ if $@;
+  croak _clean_msg $@ if $@;
  }
  return $call;
 }
@@ -240,7 +248,7 @@ If you plan to recall several times, consider using L</wrap> instead.
 
 sub recall {
  my $wrap = eval { wrap shift };
- croak $@ if $@;
+ croak _clean_msg $@ if $@;
  return $wrap->(@_);
 }