MrNobo1024 has asked for the wisdom of the Perl Monks concerning the following question:

How come "undef = 1" creates an error but "(undef) = 1" dosen't?

Replies are listed 'Best First'.
Re: undef as an lvalue
by merlyn (Sage) on Feb 25, 2001 at 09:59 UTC
    Because that's the way it works. From perldata:
    You may assign to undef in a list. This is useful for throwing away some of the return values of a function: ($dev, $ino, undef, undef, $uid, $gid) = stat($file);

    -- Randal L. Schwartz, Perl hacker

      What shall we call these? "Ephemeral list elements"? As you know, merlyn, they actually last a little longer then that piece of doc implies. They are not just immediately thrown away. They last long enough for us to grab the value that undef held a place for. Some examples will help here:
      my @w = () = 1; print "[", @w, "]\n"; # prints: [] my @x = (undef) = 2; print "[", @x, "]\n"; # prints: [2] my @y = (undef) = (3,4); print "[", @y, "]\n"; # prints: [3] my @z = (undef, undef) = (5,6); print "[", @z, "]\n"; # prints: [56] my $temp; my @z = (undef, $temp, undef) = (7,8,9); print "[", @z, "]\n"; # prints: [789]
      All of which is related to but a bit different from the following which (like the first example above) does not return values-in-a-list but still manages to force a list context for what will be returned by the regex (or any other expression that can return scalar or list). That elusive ghost list can then be construed into a scalar count of the list elements:
      my $count = () = "abacadaeafag" =~ /a/g; my @empty = () = "abacadaeafag" =~ /a/g; print "[", $count, "]\n"; # prints: [6] print "[", @empty, "]\n"; # prints: []
      Even more ephemeral. But the "$count = () = m//" construct can be handy occasionally.

      Update: a friend asked for an example of 'handy'. Herewith offered:

      $_ = "abacadaeafag"; # or whatever if ( scalar( () = /a/g ) > 7 ) { # more than 7 'hits'? # do something... }
        Are those *really* lvaluable undefs holding their values, or is it merely Perl ever-so-helpfully evaluating the expression and providing its evaluant (I can't think of the correct computer science word for this at the moment) when evaluating the expression?

        Without looking at the code, I'm 95% sure it's the latter. Why write a special case for what's already a special case?

        To illustrate what I mean, consider using an assignment as a conditional:

        if (my $y = 1) { print "Y! ($y)\n"; } print "Y is still ($y)\n";
        Scoped as you expect, and behaves as you expect. Using undef as an lvalue within a list is the special case. The fact that that assignment evaluates to what you'd expect with a regular assignment is not.
        A minor nit, the scalar in your last example is superfluous, since the numeric comparison forces the LHS into scalar context anyway:
        $_ = "abacadaeafag"; # or whatever if ( ( () = /a/g ) > 7 ) { # more than 7 'hits'? # do something... }
           MeowChow                                   
                       s aamecha.s a..a\u$&owag.print