In Perl, how to use 'defined' function on elements of two-dimensional array?
-
17-06-2021 - |
Question
I am trying to check if an element is defined, using defined function in Perl.
Code :
$mylist[0][0]="wqeqwe";
$mylist[0][1]="afasf";
$mylist[1][0]="lkkjh";
print scalar(@mylist), "\n";
if (defined($mylist[2][0])){print "TRUE\n";}
print scalar(@mylist), "\n";
Output
2
3
Before using defined function, there were two elements in first dimension of @myarray
. After using defined function, the number of elements increase to 3.
How to use defined function with out adding new elements ?
Solution
First check that the first-level reference exists.
if ( defined($mylist[2]) && defined($mylist[2][0]) ) {
print "TRUE\n";
}
What you've encountered is called autovivification: under some circumstances, Perl creates complex data structures when you use them as if they already existed.
OTHER TIPS
It's interesting to note that there's a non-core pragma called autovivification, and that if you run your code under no autovivification;
your problem will go away.
When you refer to $mylist[2][0]
, perl's autovivification creates the array element $mylist[2]
.
To prevent this, you can check this element first:
if ( (defined $mylist[2]) && (defined $mylist[2][0]) )
defined($mylist[2][0])
is equivalent to
defined($mylist[2]->[0])
which is short for
defined( ( $mylist[2] //= [] )->[0])
due to autovivification. You can disable autovivification using the autovivification pragma.
no autovivificatoin;
if (defined($mylist[2][0]))
Or you can avoid evaluating code that would trigger it.
if (defined($mylist[2]) && defined($mylist[2][0]))
Actually because it's autovivification, you can check it easily with Data::Dumper, before and after using defined.
use Data::Dumper;
my @mylist;
$mylist[0][0]="wqeqwe";
$mylist[0][1]="afasf";
$mylist[1][0]="lkkjh";
print Dumper(@mylist);
Output before
$VAR1 = ['wqeqwe', 'afasf'];
$VAR2 = [ 'lkkjh'];
print Dumper(@mylist);
Output after
$VAR1 = [ 'wqeqwe','afasf' ];
$VAR2 = ['lkkjh'];
$VAR3 = [];