is considered something of an oddity, with little practical value, but here's what I believe is a valid and defensible use of it, specifically with regards to mod_perl, and more generally with regards to any tool that wraps scripts into callable subroutines/hooks.
Those of you who've developed for mod_perl know that it's a bad idea to create global lexical variables in your
Apache::Registry scripts, since they do not stay shared when mod_perl wraps your code into a subroutine. For example, under mod_perl, the following script is transformed from:
#!/usr/bin/perl -w
...
my $fname = $q->param('fname');
my $lname = $q->param('lname');
...
sub foo {
my $name = $fname.$lname;
...
}
into a subroutine like this:
sub handler {
...
my $fname = $q->param('fname');
my $lname = $q->param('lname');
...
sub foo {
my $name = $fname.$lname;
...
}
}
As you see,
foo() becomes one of those pesky
inner named subroutines, which means that upon successive invocations of the script (or more precisely, the handler subroutine), the
$fname and
$lname variables of the inner sub will remain bound to their values from the first invocation, and will not reflect new values. This issue is
well documented in the mod_perl guide, along with several
remedies for the problem, none of which I like too much.
Looking over that discussion, it occured to me that the 'my $x if 0' construct can resolve this issue:
sub OUTER {
my $x if 0;
$x = 0;
print "OUTER: \$x is now: ", ++$x, $/;
sub INNER {
print "INNER: \$x is now: ", ++$x, $/;
}
}
OUTER;INNER;INNER;
OUTER;INNER;INNER;
## results
OUTER: $x is now: 0
INNER: $x is now: 1
INNER: $x is now: 2
OUTER: $x is now: 0
INNER: $x is now: 1
INNER: $x is now: 2
What's happening here is that successive invocations simply overwrite the values bound upon the initial invocation. Since we've cheated Perl out of enacting the run-time effect of
my $x, this allows lexical variables to stay shared between outer and inner named subroutines (despite
-w's admonitions to the contrary).
I don't think I would do something like this in production code. I'll probably stick to using package globals, perhaps with our-scoping, but it's certainly worth thinking about and perhaps incorporating as a bonified language feature in future perl releases, eg:
...
my $fname : static = $q->param('fname');
my $lname : static = $q->param('lname');
...
MeowChow
s aamecha.s a..a\u$&owag.print