in reply to Re: Re: Re: undef as an lvalue
in thread undef as an lvalue

my @y= (undef)= (3,4);

Since this sets @y to (3) not (3,4) nor (2), I think these are actually modifiably undefs. But that makes perfect sense to me considering subroutine arguments...

sub set { my( $pos, $newval )= @_; $_[$pos]= $newval; return $_[$pos]; } print set( 2, "hello", undef ), $/; # prints "hello" my $x= "one"; print set( 2, "two", $x ), $/; # prints "two", changes $x print $x, $/; # prints "two" print set( 2, "four", $x.3 ), $/; # prints "for", $x unchanged print $x, $/; # prints "two" print set( 2, "hello", "goodbye" ); # dies with: # Modification of a read-only value attempted

When you pass things to a subroutine, @_ usually ends up holding aliases to variables passed in. That is, you can modify the variables by modifying $_[2], for example. But if you pass in an expression, then the subroutine gets a copy instead of an alias.

In the case of undef, Perl has several choices: 1) It could pass in an alias to the one, read-only undefined value. 2) It could pass in a modifiable copy of the undefined value. 3) It could pass in a read-only copy of the undefined value.

In our last line of code above, Perl is passing in a alias to the read-only value "goodbye". This makes some sense in that it catches certain coding mistakes. But, since this is Perl, that is probably mostly considered unfortunate, the preference being to be flexible and allow such strange practices for which it is hard to imagine a use (until, of course, you have a use for them). So I think the real reason it does this is to avoid the overhead of copying the possibly large value.

In the case of undef, I think Perl always passes in a writeable copy because: 1) undef is never large and 2) it can be handy to pass in undef even though the subroutine intends to modify that argument. So undef can be used to mean "I don't care" about that value and the subroutine doesn't have to be coded to check for that case. Very Perlish.

So when building a list, undef is always copied and so become modifiable.

($a,undef,$b)= @x; # [undef] is copied ($a,"hi",$b)= @x; # "hi" is aliased and so this dies @x= ($a,undef,$b); # [undef] is copied so $x[1] is modifiable @x= ($a,"hi",$b); # "hi" is copied so $x[1] is modifiable
        - tye (but my friends call me "Tye")