Closed p5pRT closed 20 years ago
Consider this code that expectedly does the wrong thing:
{ my $d = 'xxx'; sub foo { my ($b\, $c); $b = '$d'; $c = eval("\"$b\""); print "$c\n"; } } foo();
No problem here: Perl doesn't see that foo() contains a hidden reference to $d and so the garbage collector has already cleaned up $d when foo() is called.
But what about this here:
{ my $d; sub foo { my ($b\, $c); $b = '$d'; $c = eval("\"$b\""); print "$c\n"; } sub bar { $d = 'xxx'; foo(); } } bar();
In my understanding\, the mentioning of $d in bar should keep $d alive by the time foo() is called.
I am not sure\, whether this is a known issue.
On approximately 1/12/2004 2:20 AM\, came the following characters from the keyboard of Tassilo v.Parseval (via RT):
But what about this here:
\{ my $d; sub foo \{ my \($b\, $c\); $b = '$d'; $c = eval\("\\"$b\\""\); print "$c\\n"; \} sub bar \{ $d = 'xxx'; foo\(\); \} \} bar\(\);
In my understanding\, the mentioning of $d in bar should keep $d alive by the time foo() is called.
I am not sure\, whether this is a known issue.
This was beaten to death in the "ignorant wumpus" thread due to my ignorance.
Now\, to hopefully save Dave a few of the tuits he used in that threads\, what you have there in your example is two separate subs\, 'foo' does not reference $d visibly (to the compiler at compile time) and 'bar' does\, and therefore becomes a closure.
The fact that the subs are enclosed in the same {} with the my $d does not make the pair of them a single closure. The fact that 'bar' contains a visible outer reference to $d is what makes it a closure\, but that does not affect and is not affected by 'foo' or the block containing $d.
Since 'foo' is not a closure\, it does not retain a reference to the original $d\, and when later invoked a new $d of the appropriate scope is instantiated (and undef). Since 'bar' is a closure\, it retains a reference to the original value $d\, and modifies that original value. However\, 'bar's reference to $d is lexical in nature\, and is not shared by 'foo'.
So\, this is working as advertised. Or as it will be advertised\, once Dave's tuit supply allows him to finish his documentation improvements for closures.
The best part about procrastination is that you are never bored\, because you have all kinds of things that you should be doing.
The RT System itself - Status changed from 'new' to 'open'
On Tue\, Jan 13\, 2004 at 05:04:39AM +0000 Glenn Linderman via RT wrote:
On approximately 1/12/2004 2:20 AM\, came the following characters from the keyboard of Tassilo v.Parseval (via RT):
But what about this here:
\{ my $d; sub foo \{ my \($b\, $c\); $b = '$d'; $c = eval\("\\"$b\\""\); print "$c\\n"; \} sub bar \{ $d = 'xxx'; foo\(\); \} \} bar\(\);
In my understanding\, the mentioning of $d in bar should keep $d alive by the time foo() is called.
I am not sure\, whether this is a known issue.
This was beaten to death in the "ignorant wumpus" thread due to my ignorance.
Now\, to hopefully save Dave a few of the tuits he used in that threads\, what you have there in your example is two separate subs\, 'foo' does not reference $d visibly (to the compiler at compile time) and 'bar' does\, and therefore becomes a closure.
[ further explanation ]
Thanks for the details. I must have missed the thread you mentioned. So what happens does in fact contradict the concept of closures I had so far. Good that this is going to be documented.
Tassilo -- $_=q#"\,}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({ pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#; $_=reverse\,s+(?\<=sub).+q#q!'"qq.\t$&."'!#+sexisexiixesixeseg;y~\n~~dddd;eval
@rgs - Status changed from 'open' to 'resolved'
Migrated from rt.perl.org#24881 (status was 'resolved')
Searchable as RT24881$