With warnings enabled, perl usually prints Use of uninitialized value $foo
if $foo
is used in an expression and hasn't been assigned a value, but in some cases it's OK, and the variable is treated as false, 0
, or ''
without a warning.
What are the cases where an uninitialized/undefined variable can be used without a warning?
use warnings; When the warning pragma is used, the compiler will check for errors, will issue warnings against the code, and will disallow certain programming constructs and techniques. This pragma sends a warning whenever a possible typographical error and looks for possible problems.
Perl | defined() Function Defined() in Perl returns true if the provided variable 'VAR' has a value other than the undef value, or it checks the value of $_ if VAR is not specified. This can be used with many functions to detect for the failure of operation since they return undef if there was a problem.
undef is used for those variables which do not have any assigned value. One can compare it with NULL(in Java, PHP etc.) and Nil(in Ruby). So basically when the programmer will declare a scalar variable and don't assign a value to it then variable is supposed to be contain undef value.
To tell if a variable has already been defined in a perl program, you can use the function defined . If you wish to wipe away all traces of a variable at some point in a program, you can use the undef function, or simply set the variable equal to the value undef .
According to the perlsyn documentation,
The number
0
, the strings'0'
and''
, the empty list()
, andundef
are all false in a boolean context. All other values are true.
Because the undefined value is false, the following program
#! /usr/bin/perl
use warnings;
my $var;
print "A\n" if $var;
$var && print "B\n";
$var and print "C\n";
print "D\n" if !$var;
print "E\n" if not $var;
$var or print "F\n";
$var || print "G\n";
outputs D
through G
with no warnings.
There's no need to explicitly initialize a scalar to zero if your code will increment or decrement it at least once:
#! /usr/bin/perl
use warnings;
my $i;
++$i while "aaba" =~ /a/g;
print $i, "\n";
The code above outputs 3
with no warnings.
Similar to the implicit zero, there's no need to explicitly initialize scalars to the empty string if you'll append to it at least once:
#! /usr/bin/perl
use warnings;
use strict;
my $str;
for (<*>) {
$str .= substr $_, 0, 1;
}
print $str, "\n";
One example is "autovivification." From the Wikipedia article:
Autovivification is a distinguishing feature of the Perl programming language involving the dynamic creation of data structures. Autovivification is the automatic creation of a variable reference when an undefined value is dereferenced. In other words, Perl autovivification allows a programmer to refer to a structured variable, and arbitrary sub-elements of that structured variable, without expressly declaring the existence of the variable and its complete structure beforehand.
For example:
#! /usr/bin/perl
use warnings;
my %foo;
++$foo{bar}{baz}{quux};
use Data::Dumper;
$Data::Dumper::Indent = 1;
print Dumper \%foo;
Even though we don't explicitly initialize the intermediate keys, Perl takes care of the scaffolding:
$VAR1 = { 'bar' => { 'baz' => { 'quux' => '1' } } };
Without autovivification, the code would require more boilerplate:
my %foo;
$foo{bar} = {};
$foo{bar}{baz} = {};
++$foo{bar}{baz}{quux}; # finally!
Don't confuse autovivification with the undefined values it can produce. For example with
#! /usr/bin/perl
use warnings;
my %foo;
print $foo{bar}{baz}{quux}, "\n";
use Data::Dumper;
$Data::Dumper::Indent = 1;
print Dumper \%foo;
we get
Use of uninitialized value in print at ./prog.pl line 6. $VAR1 = { 'bar' => { 'baz' => {} } };
Notice that the intermediate keys autovivified.
Other examples of autovivification:
reference to array
my $a;
push @$a => "foo";
reference to scalar
my $s;
++$$s;
reference to hash
my $h;
$h->{foo} = "bar";
Sadly, Perl does not (yet!) autovivify the following:
my $code;
$code->("Do what I need please!");
In an answer to a similar question, ysth reports
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-),+=
,-=
,.=
,|=
,^=
,&&=
,||=
.
Being "defined-or," //=
happily mutates an undefined value without warning.
So far the cases I've found are:
if $foo
or $foo || $bar
++
or --
+=
, -=
, or .=
Are there others?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With