Perhaps I'm being too simple-minded, but please consider this variant:
use strict qw(vars subs);
my $name;
{
my $name = 'red';
*$name = sub { "<FONT COLOR='$name'>@_</FONT>" };
}
{
my $name = 'blue';
*$name = sub { "<FONT COLOR='$name'>@_</FONT>" };
}
$name = '<none>';
print red(), "\n";
print blue(), "\n";
__END__
<FONT COLOR='red'></FONT>
<FONT COLOR='blue'></FONT>
Without the additional block delimiters ({}) and my declarations, the variable $name indeed always refers to the same storage (which, I admit, was not clear in my own mind when I wrote the above comment). Closures (red() and blue() here) only get a copy of a portion of their lexical environment (that is, become "closures", properly so-called) when they escape a region where that portion is (lexically, of course) in scope. Without a block that the thread of execution leaves, no closure is created and the code is indistinguishable from a regular sub.
Note that red() and blue() (i.e. &red and &blue) exist outside the blocks because they are created in the package's (here, main) symbol table -- as using a type glob (*) always implies.
Here's the code with another wrinkle to illustrate:
use strict qw(vars subs);
{
my $name;
{ my $name = 'red';
*$name = sub { "<FONT COLOR='$name'>@_</FONT>" }; }
{ my $name = 'blue';
*$name = sub { "<FONT COLOR='$name'>@_</FONT>" }; }
*foo = sub {
print red($name), "\n";
print blue($name), "\n";
};
$name = 'another wrinkle';
}
foo();
print red('hi mom');
__END__
<FONT COLOR='red'>another wrinkle</FONT>
<FONT COLOR='blue'>another wrinkle</FONT>
<FONT COLOR='red'>hi mom</FONT>
| [reply] [d/l] [select] |