muthm has asked for the wisdom of the Perl Monks concerning the following question:
In the middle of editing and restructuring some code, I happened to have the initialization of a lexical variable at the beginning of a subroutine expressed like this:
my $my_var = "default" unless defined $param; $my_var //= $param;
Clearly, this could (and maybe should) be written much nicer as my $my_var = $param // "default"; but at that point I wanted to verify some other things and ran the above version.
When I called the subroutine several times for testing, with different parameters, I had results that seem strange to me.
The lexical variable, of which I thought it would be created as undef for each call to the subroutine, kept its value from one call to another
if the condition for the initialization was false.
The following program shows what I mean:
The output is:#!/usr/bin/env perl use strict; use warnings; use feature 'say'; use feature 'signatures'; no warnings 'experimental::signatures'; use Data::Dump qw( pp ); sub foo( $param ) { say "\$param is ", pp( $param ); my $my_var = "default" unless defined $param; say "\$my_var after declaration is ", pp( $my_var ); say +( defined $param ? ! defined $my_var : defined $my_var && $my_var eq 'default' ) ? " (as expected)" : " (unexpected to me!)"; $my_var //= $param; say "\$my_var after '//=' is ", pp( $my_var ); say ""; return $my_var; } foo( $_ ) for undef, "call 1", "call 2", "call 3"; 1;
$ ./my_with_if.pl $param is undef $my_var after declaration is "default" (as expected) $my_var after '//=' is "default" $param is "call 1" $my_var after declaration is undef (as expected) $my_var after '//=' is "call 1" $param is "call 2" $my_var after declaration is "call 1" (unexpected to me!) $my_var after '//=' is "call 1" $param is "call 3" $my_var after declaration is "call 1" (unexpected to me!) $my_var after '//=' is "call 1"
The point is that $my_var still contains the "call 1" value from the previous call in the "call 2" call.
Why isn't it undef?
I also find it interesting to see that $my_var *is* initialized to undef as I would expect in the "call 1" call,
where the value from the call before was the "default" value. This means that the value is not *always* kept from the call before!
Very strange!
Did I find a bug in the conditional initialization of lexical (my) variables?
Or maybe it is just an unspecified (or 'undefined' :-)) behavior?
Which would explain that I didn't find any specific explanation in the Perldoc (Private Variables via my())?
Thank you for your help!
Matthias
|
|---|