Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When does Perl auto-initialize variables?

Here is some simple Perl to count the number of times a value occurs in an array. This runs without any warnings.

use warnings;
use strict;

my @data = qw(1 1 2 3 4 5 5 5 9);
my %histogram;
foreach (@data)
{
    $histogram{$_}++;
}

When the loop body is changed to

$histogram{$_} = $histogram{$_} + 1;

Perl warns "Use of uninitialized value in addition".

What is going on under the hood? Why is the value initialized when supplied as an operand to the ++ operator and uninitialized with the + operator?

like image 405
Andrew Avatar asked Nov 04 '08 02:11

Andrew


People also ask

What does @_ do in Perl?

Using the Parameter Array (@_) Perl lets you pass any number of parameters to a function. The function decides which parameters to use and in what order. The @_ array is used like any other array.

What does $@ meaning in Perl?

The variables are shown ordered by the "distance" between the subsystem which reported the error and the Perl process...$@ is set if the string to be eval-ed did not compile (this may happen if open or close were imported with bad prototypes), or if Perl code executed during evaluation die()d.

What is $$ in Perl?

$$ The process number of the perl running this script. (Mnemonic: same as shells.) $? The status returned by the last pipe close, backtick (\`\`) command or system operator.

How do I declare a variable in Perl?

Perl variables do not have to be explicitly declared to reserve memory space. The declaration happens automatically when you assign a value to a variable. The equal sign (=) is used to assign values to variables.


3 Answers

The + operator evaluates both the form to the left and the form to the right of it, then returns the sum of both. The hash call evaluation does not see any special context.

The ++ operator has some special magic built in. Quoting from the perlop manpage, regarding the ++ operator:

"undef" is always treated as numeric, and in particular is changed to 0 before incrementing (so that a post-increment of an undef value will return 0 rather than "undef").

edit: To elaborate on the difference, ++ changes the value in place, while + just takes its arguments as input. When + sees an undefined value, typically something has gone wrong, but for ++, your hash manipulation example is very typical -- the user wants to treat undef as 0, instead of having to check and initialize everytime. So it seems that it makes sense to treat these operators this way.

like image 170
Svante Avatar answered Sep 19 '22 19:09

Svante


It's not that Perl necessarily initializes values, but that it doesn't always warn about them. Don't try to think about a rule for this because you'll always find exceptions, and just when you think you have it figured out, the next version of Perl will change the warnings on you.

In this case, as Harleqin said, the auto-increment operators have a special case.

like image 33
brian d foy Avatar answered Sep 22 '22 19:09

brian d foy


Certain operators deliberately omit the "uninitialized" warning for your convenience because they are commonly used in situations where a 0 or "" default value for the left or only operand makes sense.

These are: ++ and -- (either pre or post), +=, -=, .=, |=, ^=, &&=, ||=.

Note that some of these erroneously give the warning when used on a tied variable: see the tests marked TODO in http://perl5.git.perl.org/perl.git/blob/HEAD:/t/op/assignwarn.t.

like image 32
ysth Avatar answered Sep 18 '22 19:09

ysth