http://qs321.pair.com?node_id=1222125

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

...and is it a good idea? I found today in one of my own programs:

use strict; use warnings; #... #... my $s; # declared, but uninitialized #... #... $s .= some_expression() for @some_list;

And Perl said nothing. Quick check shows, that those of "combined assignment operators" which can be classified as "adders", or which assign (and thus return) their RH argument, if LH argument is uninitialized (i.e. +=, -=, .=, |=, ^=, ||=, //=) (well, negated in case of -=, of course), do not produce a warning. While others do. Therefore, it looks like it was done on purpose. It seems DWIMish, and thus maybe a right thing to do, but is it documented, at least?

  • Comment on Some "combined assignment operators" are exempt from "uninitialized value" warning. Is it documented anywhere?
  • Select or Download Code

Replies are listed 'Best First'.
Re: Some "combined assignment operators" are exempt from "uninitialized value" warning. Is it documented anywhere?
by Eily (Monsignor) on Sep 11, 2018 at 15:16 UTC

    You don't get a warning when undef is interpreted as the identity element of the operator. Or, in other words, when the following pattern isn't useless

    my $value; while (condition) # or for loop { $value <op>= something; }
    For example:
    my $sum; $sum += $_ for @nums;
    or
    my $valid; while (<DATA>) { chomp; next if /INVALID/; $valid .= $_; }
    And not setting the variable before the loop let's you tell if there were no valid lines at all, or if the only valid data was empty strings (or $sum will be undef rather than 0 if there are no numbers).

    On the other hand you can use whatever values you want, this will never yield anything but 0:

    my $product; $product *= $_ for @nums;
    This can only be a mistake.

    So this would tend towards "this a right thing to do", but I couldn't find the documentation either.

    Edit: that was full of typos. I wrote "under" for "undef", "is" for "if" and "identify" for "identity". I hope I got them all...

      Here's one case where it won't be zero (undef instead), but it isn't very useful.
      >perl -e "use warnings; my @nums = (); my $prod; $prod *= $_ for @nums +; print $prod" Use of uninitialized value $prod in print at -e line 1.
Re: Some "combined assignment operators" are exempt from "uninitialized value" warning. Is it documented anywhere?
by Anonymous Monk on Sep 12, 2018 at 18:50 UTC
    When I was new to Perl uninitialized values were the bane of my existence. Many traps are eliminated simply by initializing all variables. It's useful to init strings to '' and numbers to 0 so they can be freely checked and used after declaration without having to worry about init errors. If there's a problem with the program it will display the init values instead of crashing with an error. My preference is always: not to crash.
    my $value; # Error if condition fails. my $value = ''; # Empty if condition fails. if (condition) { $value += 'something' } print "The value is $value";