Allow prototypes (_@) and (_%)
authorRafael Garcia-Suarez <rgs@consttype.org>
Fri, 27 Jan 2012 09:23:12 +0000 (10:23 +0100)
committerRafael Garcia-Suarez <rgs@consttype.org>
Fri, 27 Jan 2012 09:23:12 +0000 (10:23 +0100)
Those will be equivalent to (_;@) and (_;%) ; since perlsub already
states that the semicolon is redundant before @ and % this is in
line with the existing documentation.

op.c
pod/perlsub.pod
t/comp/uproto.t
toke.c

diff --git a/op.c b/op.c
index 30cc7f8..479d2ba 100644 (file)
--- a/op.c
+++ b/op.c
@@ -9145,7 +9145,7 @@ Perl_ck_entersub_args_proto(pTHX_ OP *entersubop, GV *namegv, SV *protosv)
                continue;
            case '_':
                /* _ must be at the end */
-               if (proto[1] && proto[1] != ';')
+               if (proto[1] && !strchr(";@%", proto[1]))
                    goto oops;
            case '$':
                proto++;
index 1add95f..9d6fd25 100644 (file)
@@ -1136,9 +1136,9 @@ is of an acceptable type.
 A semicolon (C<;>) separates mandatory arguments from optional arguments.
 It is redundant before C<@> or C<%>, which gobble up everything else.
 
-As the last character of a prototype, or just before a semicolon, you can
-use C<_> in place of C<$>: if this argument is not provided, C<$_> will be
-used instead.
+As the last character of a prototype, or just before a semicolon, a C<@>
+or a C<%>, you can use C<_> in place of C<$>: if this argument is not
+provided, C<$_> will be used instead.
 
 Note how the last three examples in the table above are treated
 specially by the parser.  C<mygrep()> is parsed as a true list
index a7675a3..d3ad19f 100644 (file)
@@ -1,6 +1,6 @@
 #!perl
 
-print "1..39\n";
+print "1..43\n";
 my $test = 0;
 
 sub failed {
@@ -120,6 +120,21 @@ $expected = $_ = "mydir"; mymkdir();
 mymkdir($expected = "foo");
 $expected = "foo 493"; mymkdir foo => 0755;
 
+sub mylist (_@) { is("@_", $expected, "mylist") }
+$expected = "foo";
+$_ = "foo";
+mylist();
+$expected = "10 11 12 13";
+mylist(10, 11 .. 13);
+
+sub mylist2 (_%) { is("@_", $expected, "mylist2") }
+$expected = "foo";
+$_ = "foo";
+mylist2();
+$expected = "10 a 1";
+my %hash = (a => 1);
+mylist2(10, %hash);
+
 # $_ says modifiable, it's not passed by copy
 
 sub double(_) { $_[0] *= 2 }
diff --git a/toke.c b/toke.c
index baa21d6..7893eb4 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -8150,7 +8150,7 @@ Perl_yylex(pTHX)
                                }
                                else {
                                    if ( underscore ) {
-                                       if ( *p != ';' )
+                                       if ( !strchr(";@%", *p) )
                                            bad_proto = TRUE;
                                        underscore = FALSE;
                                    }