]> git.vpit.fr Git - perl/modules/Sub-Prototype-Util.git/blobdiff - lib/Sub/Prototype/Util.pm
Replace tail recursion in _wrap() by a while loop
[perl/modules/Sub-Prototype-Util.git] / lib / Sub / Prototype / Util.pm
index 91520b823361f417e9d715e1d3f7f63d4888a04e..d549a1cc992e8ea86ceac04a35f89d11a7207098 100644 (file)
@@ -72,19 +72,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 +139,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 +175,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 {