multidimensional hash modified by test

M

Mike Solomon

I ran the following script and got what I consider to be a strange result


my %data;

$data{a}{a} = 1;

my $total = keys %data;

print "$total\n";

#prints 1

print "NOT IN HASH\n" unless $data{b}{b};

#prints NOT IN HASH
$total = keys %data;

print "$total\n";

#prints 2

Why does the total keys increase to 2 when I test for non existent data?

Thanks
 
A

A. Sinan Unur

(e-mail address removed) (Mike Solomon) wrote in
I ran the following script and got what I consider to be a strange result


my %data;

$data{a}{a} = 1;

my $total = keys %data;

print "$total\n";

#prints 1

print "NOT IN HASH\n" unless $data{b}{b};

This autovivifies $data{b}.

....
Why does the total keys increase to 2 when I test for non existent data?

You should use exists if you want to test for existence:

perldoc -f exists

Sinan
 
X

xhoster

I ran the following script and got what I consider to be a strange result

my %data;

$data{a}{a} = 1;

my $total = keys %data;

print "$total\n";

#prints 1

print "NOT IN HASH\n" unless $data{b}{b};

#prints NOT IN HASH
$total = keys %data;

print "$total\n";

#prints 2

Why does the total keys increase to 2 when I test for non existent data?

It is called autovivification. You can read about it in perldoc perlref.

Xho
 
L

LEH

A. Sinan Unur said:
(e-mail address removed) (Mike Solomon) wrote in


This autovivifies $data{b}.

...


You should use exists if you want to test for existence:

perldoc -f exists

Sinan

using exists,
ie. print "NOT IN HASH\n" unless exists $data{b}{b};
also seems to autovivify $data{b}

according to perldoc -f exists

if (exists &{$ref->{A}{B}{$key}}) { }
Although the deepest nested array or hash will not spring into
existence just because its existence was tested, any intervening
ones will. Thus "$ref->{"A"}" and "$ref->{"A"}->{"B"}" will
spring into existence due to the existence test for the $key
element above.

Larry
 
L

LEH

LEH said:
using exists,
ie. print "NOT IN HASH\n" unless exists $data{b}{b};
also seems to autovivify $data{b}

according to perldoc -f exists

if (exists &{$ref->{A}{B}{$key}}) { }
Although the deepest nested array or hash will not spring into
existence just because its existence was tested, any intervening
ones will. Thus "$ref->{"A"}" and "$ref->{"A"}->{"B"}" will
spring into existence due to the existence test for the $key
element above.

Larry
but this works
print "NOT IN HASH\n" unless exists $data{b} && $data{b}{b};
although perhaps there is a better way.
Larry
 
A

A. Sinan Unur

....

according to perldoc -f exists

if (exists &{$ref->{A}{B}{$key}}) { } ....
ones will. Thus "$ref->{"A"}" and "$ref->{"A"}->{"B"}" will
spring into existence due to the existence test for the $key
element above.

Aaaah ... I don't know how I forgot that but thanks for catching the
error.

Sinan.
 
M

Mike Solomon

A. Sinan Unur said:
(e-mail address removed) (Mike Solomon) wrote in


This autovivifies $data{b}.

...


You should use exists if you want to test for existence:

perldoc -f exists

Sinan

Thanks everyone

By the way it behaves exactly the same way if you use exists
 
A

Anno Siegel

LEH said:
[...]
using exists,
ie. print "NOT IN HASH\n" unless exists $data{b}{b};
also seems to autovivify $data{b}

according to perldoc -f exists

if (exists &{$ref->{A}{B}{$key}}) { }
Although the deepest nested array or hash will not spring into
existence just because its existence was tested, any intervening
ones will. Thus "$ref->{"A"}" and "$ref->{"A"}->{"B"}" will
spring into existence due to the existence test for the $key
element above.

Larry
but this works
print "NOT IN HASH\n" unless exists $data{b} && $data{b}{b};
although perhaps there is a better way.

You need "exists" in front of "$data{b}{b}" too. As written, it will
still autovivify $data{ b}->{ b} if only $data{ b} exists. Also, it
will fail (claim nonexistence) if $data{ a}->{ a} is defined but false.

Anno
 
X

xhoster

You need "exists" in front of "$data{b}{b}" too.

True, but....
As written, it will
still autovivify $data{ b}->{ b} if only $data{ b} exists.

$data{ b}->{ b} is not used in a hashref-like context, so there is nothing
to autovivify, whether the "exists" is added or not.
Also, it
will fail (claim nonexistence) if $data{ a}->{ a} is defined but false.

Yes, that is true.

Xho
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,169
Messages
2,570,919
Members
47,459
Latest member
Vida00R129

Latest Threads

Top