summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÆvar Arnfjörð Bjarmason <avar@cpan.org>2014-05-10 09:26:14 +0000
committerRicardo Signes <rjbs@cpan.org>2014-05-12 10:59:31 -0400
commitfe39f0d59b87549f2e6cb1df1dfeaa25215b19ab (patch)
tree6a650de9320f83cf0cb86a367d47d56dacd94609
parent9e153387d111262bc785c0e9ee5ecc62fea55a79 (diff)
downloadperl-fe39f0d59b87549f2e6cb1df1dfeaa25215b19ab.tar.gz
perlsub: Improve the "Constant Functions" documentation
Ever since perl-5.003_95-19-g5431012 which incorporated this patch: Title: "Improve and update documentation of constant subs" From: Tom Phoenix <rootbeer@teleport.com> Msg-ID: <Pine.GSO.3.96.970331122546.14185C-100000@kelly.teleport.com> Date: Mon, 31 Mar 1997 13:05:54 -0800 (PST) Files: pod/perlsub.pod We've documented that "BEGIN { my $x = 1; *X = sub () { $x } }" creates an inlined subroutine, we just weren't doing so very explicitly. Patch the documentation so that we now have explicit examples for the behavior mentioned in the first paragraph of the section. This also adds an explicit mention of the behavior reported as a bug in [RT #79908], shows the user that you can just use B::Deparse rather than relying on a warning to see the effects of inlining, and replaces a contrived way to avoid inlining with just adding a "return". While writing these docs I found a bug in the warning behavior mentioned here, which I filed as [RT #121841]
-rw-r--r--pod/perlsub.pod88
1 files changed, 75 insertions, 13 deletions
diff --git a/pod/perlsub.pod b/pod/perlsub.pod
index bf082628e0..daa25bc042 100644
--- a/pod/perlsub.pod
+++ b/pod/perlsub.pod
@@ -1653,20 +1653,82 @@ the constant folding doesn't reduce them to a single constant:
}
}
-If you redefine a subroutine that was eligible for inlining, you'll get
-a warning by default. (You can use this warning to tell whether or not a
-particular subroutine is considered inlinable.) The warning is
-considered severe enough not to be affected by the B<-w>
-switch (or its absence) because previously compiled
-invocations of the function will still be using the old value of the
-function. If you need to be able to redefine the subroutine, you need to
-ensure that it isn't inlined, either by dropping the C<()> prototype
-(which changes calling semantics, so beware) or by thwarting the
-inlining mechanism in some other way, such as
-
- sub not_inlined () {
- 23 if $];
+As alluded to earlier you can also declare inlined subs dynamically at
+BEGIN time if their body consists of a lexically-scoped scalar which
+has no other references. Only the first example here will be inlined:
+
+ BEGIN {
+ my $var = 1;
+ no strict 'refs';
+ *INLINED = sub () { $var };
+ }
+
+ BEGIN {
+ my $var = 1;
+ my $ref = \$var;
+ no strict 'refs';
+ *NOT_INLINED = sub () { $var };
+ }
+
+A not so obvious caveat with this (see [RT #79908]) is that the
+variable will be immediately inlined, and will stop behaving like a
+normal lexical variable, e.g. this will print C<79907>, not C<79908>:
+
+ BEGIN {
+ my $x = 79907;
+ *RT_79908 = sub () { $x };
+ $x++;
+ }
+ print RT_79908(); # prints 79907
+
+If you really want a subroutine with a C<()> prototype that returns a
+lexical variable you can easily force it to not be inlined by adding
+an explicit C<return>:
+
+ BEGIN {
+ my $x = 79907;
+ *RT_79908 = sub () { return $x };
+ $x++;
+ }
+ print RT_79908(); # prints 79908
+
+The easiest way to tell if a subroutine was inlined is by using
+L<B::Deparse>, consider this example of two subroutines returning
+C<1>, one with a C<()> prototype causing it to be inlined, and one
+without (with deparse output truncated for clarity):
+
+ $ perl -MO=Deparse -le 'sub ONE { 1 } if (ONE) { print ONE if ONE }'
+ sub ONE {
+ 1;
+ }
+ if (ONE ) {
+ print ONE() if ONE ;
}
+ $ perl -MO=Deparse -le 'sub ONE () { 1 } if (ONE) { print ONE if ONE }'
+ sub ONE () { 1 }
+ do {
+ print 1
+ };
+
+If you redefine a subroutine that was eligible for inlining, you'll
+get a warning by default. You can use this warning to tell whether or
+not a particular subroutine is considered inlinable, since it's
+different than the warning for overriding non-inlined subroutines:
+
+ $ perl -e 'sub one () {1} sub one () {2}'
+ Constant subroutine one redefined at -e line 1.
+ $ perl -we 'sub one {1} sub one {2}'
+ Subroutine one redefined at -e line 1.
+
+The warning is considered severe enough not to be affected by the
+B<-w> switch (or its absence) because previously compiled invocations
+of the function will still be using the old value of the function. If
+you need to be able to redefine the subroutine, you need to ensure
+that it isn't inlined, either by dropping the C<()> prototype (which
+changes calling semantics, so beware) or by thwarting the inlining
+mechanism in some other way, e.g. by adding an explicit C<return>:
+
+ sub not_inlined () { return 23 }
=head2 Overriding Built-in Functions
X<built-in> X<override> X<CORE> X<CORE::GLOBAL>