summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael Garcia-Suarez <rgs@consttype.org>2012-01-27 10:23:12 +0100
committerRafael Garcia-Suarez <rgs@consttype.org>2012-01-27 10:23:12 +0100
commit34daab0fa047b2849547189ae5f48b276658af01 (patch)
tree055f01d40f5578da8c21a22e3ce4fad400f29722
parentcc2cb33e7c6571bb162ba54eeb5765e0edcd76d1 (diff)
downloadperl-34daab0fa047b2849547189ae5f48b276658af01.tar.gz
Allow prototypes (_@) and (_%)
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.
-rw-r--r--op.c2
-rw-r--r--pod/perlsub.pod6
-rw-r--r--t/comp/uproto.t17
-rw-r--r--toke.c2
4 files changed, 21 insertions, 6 deletions
diff --git a/op.c b/op.c
index 30cc7f8a95..479d2ba10e 100644
--- 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++;
diff --git a/pod/perlsub.pod b/pod/perlsub.pod
index 1add95f8f6..9d6fd25188 100644
--- a/pod/perlsub.pod
+++ b/pod/perlsub.pod
@@ -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
diff --git a/t/comp/uproto.t b/t/comp/uproto.t
index a7675a3fcb..d3ad19f849 100644
--- a/t/comp/uproto.t
+++ b/t/comp/uproto.t
@@ -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 baa21d602b..7893eb48f7 100644
--- 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;
}