summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Martini <PeterCMartini@GMail.com>2013-08-06 03:16:35 -0400
committerFather Chrysostomos <sprout@cpan.org>2013-08-06 05:53:07 -0700
commiteb40d2ca32bab47c140b354a1907b0ba5b74f9bc (patch)
tree926a5446502b2b60e6390b9e1b3c86a9c270150c
parent51da40ed5ad9513dc5f2213b76a414e9eb4c239d (diff)
downloadperl-eb40d2ca32bab47c140b354a1907b0ba5b74f9bc.tar.gz
[perl #2726] Prototype is not applied until BLOCK is defined
In the case of a sub definition with a prototype, the prototype is not attached to the sub until after the body is completely defined. This means that any sub which calls itself will not honor its prototype unless the prototype was declared prior to the sub's definition. Whether or not this behavior is desirable is debatable, but its far too late to do anything about it other than document it and test to make sure it doesn't change.
-rw-r--r--pod/perlsub.pod10
-rw-r--r--t/comp/proto.t9
2 files changed, 18 insertions, 1 deletions
diff --git a/pod/perlsub.pod b/pod/perlsub.pod
index ff5feb5dc3..455fa2393a 100644
--- a/pod/perlsub.pod
+++ b/pod/perlsub.pod
@@ -1338,6 +1338,16 @@ C<func()> now gets passed in a C<1>; that is, the number of elements
in C<@foo>. And the C<split> gets called in scalar context so it
starts scribbling on your C<@_> parameter list. Ouch!
+If a sub has both a PROTO and a BLOCK, the prototype is not applied
+until after the BLOCK is completely defined. This means that a recursive
+function with a prototype has to be predeclared for the prototype to take
+effect, like so:
+
+ sub foo($$);
+ sub foo($$) {
+ foo 1, 2;
+ }
+
This is all very powerful, of course, and should be used only in moderation
to make the world a better place.
diff --git a/t/comp/proto.t b/t/comp/proto.t
index 947a2327a0..47ebf74749 100644
--- a/t/comp/proto.t
+++ b/t/comp/proto.t
@@ -18,7 +18,7 @@ BEGIN {
# strict
use strict;
-print "1..199\n";
+print "1..201\n";
my $i = 1;
@@ -559,6 +559,13 @@ print "ok ", $i++, " star3 STDERR\n";
print "not " unless eval 'star4 STDERR; 1';
print "ok ", $i++, " star4 STDERR\n";
+# [perl #2726]
+# Test that prototype binding is late
+print "not " unless eval 'sub l564($){ l564(); } 1';
+print "ok ", $i++, " prototype checking not done within initial definition\n";
+print "not " if eval 'sub l566($); sub l566($){ l566(); } 1';
+print "ok ", $i++, " prototype checking done if sub pre-declared\n";
+
# test scalarref prototype
sub sreftest (\$$) {
print "not " unless ref $_[0];