If a closure is "a special case of an anonymous subroutine holding onto data that used to belong to its scope at the time of its creation" (S.Srinivasan in
Advanced Perl Programming), then your code is behaving right, although strict has failed to detect that $x within the anonymous sub isn't referring to the same $x within the grand-parent scope.
However, having said that, though anonymous subroutines are oblivious to lexicals in a grand-parent scope, normal subroutines aren't, also a normal subroutine might not derive and use a set of parent lexicals but its "children" subroutines might do, so the characteristic is intranstive, consider the following..
sub test_sub {
print &{+shift};
}
{
my $x = "hello";
my $y = "world";
local $, = " : ";
print "x - local lexical1 : $x ", \$x;
print "y - local lexical1 : $y ", \$y;
sub foo {
test_sub( sub { "x - derived lexical (anon) : $x ", \$x } );
print "y - derived lexical (foo) : $y ", \$y;
test_sub( sub { "y - derived lexical (anon) : $y ", \$y } );
sub bar {
sub baz {
print "x - derived lexical (baz) : $x ", \$x;
}
}
}
print "x - local lexical2 : $x ", \$x;
print "y - local lexical2 : $y ", \$y;
}
foo();
baz();
__END__
__output__
x - local lexical1 : hello : SCALAR(0x814c630)
y - local lexical1 : world : SCALAR(0x814c6f0)
x - local lexical2 : hello : SCALAR(0x814c630)
y - local lexical2 : world : SCALAR(0x814c6f0)
Use of uninitialized value in concatenation (.) or string at foo line
+17.
x - derived lexical (anon) : SCALAR(0x814bc28)
y - derived lexical (foo) : world SCALAR(0x814c6f0)
y - derived lexical (anon) : world SCALAR(0x814c6f0)
x - derived lexical (baz) : hello SCALAR(0x814c630)
Notice, that within foo() \$x refers to a different location than \$x in the parent scope.
To better redefine a closure: "A closure is an anonymous subroutine accessing the
immediate local scope at the time of its creation" (atleast for <= perl 5.8.x). So, it might be better to ensure that all lexicals needed to be squirreled away by a closure are explicitly typed within the immediate local scope.
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
| |
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.