S
sm
Hi,
I am having a lot of difficulty with testing to see if a hash entry is
defined/exists/etc.
I know of the problem of *surprising autovivification* in hash (
http://perldoc.perl.org/functions/exists.html)
but have not been able to find a solution that I can use (Although the
deepest nested array or hash
will not spring into existence just because its existence was tested, any
intervening ones will.)
I was womdering if anyone could help or provide a hind for a satisfactory
workaround.
#### http://perldoc.perl.org/functions/exists.html
#
# exists EXPR
#
# Given an expression that specifies a hash element or array element,
# returns true if the specified element in the hash or array has ever
# been initialized, even if the corresponding value is undefined. The
# element is not autovivified if it doesn't exist.
#
# print "Exists\n" if exists $hash{$key};
# print "Defined\n" if defined $hash{$key};
# print "True\n" if $hash{$key};
#
#
# print "Exists\n" if exists $array[$index];
# print "Defined\n" if defined $array[$index];
# print "True\n" if $array[$index];
#
# A hash or array element can be true only if it's defined, and defined
# if it exists, but the reverse doesn't necessarily hold true.
#
#
# if (exists $ref->{A}->{B}->{$key}) { }
# if (exists $hash{A}{B}{$key}) { }
#
#
# if (exists $ref->{A}->{B}->[$ix]) { }
# if (exists $hash{A}{B}[$ix]) { }
# 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. This happens anywhere
# the arrow operator is used, including even:
#
# undef $ref;
# if (exists $ref->{"Some key"}) { }
# print $ref; # prints HASH(0x80d3d5c)
#
# This surprising autovivification in what does not at first--or
# even second--glance appear to be an lvalue context may be fixed
# in a future release.
#
########################################################################
##
## This is true for *exists*, *defined* and a simple referencing
## of a hash that any of these will cause the
## *surprising autovivification*
print "\n\n", '#'x8, ' HASH behavior ', '#'x20, "\n";
print "\nchecking *exists* ", '='x50, "\n";
print "Exists\n" if exists $hash{xxx}{kkk};
print "xxx Exists\n" if exists $hash{xxx};
print "xxx,kkk Exists\n" if exists $hash{xxx}{kkk};
print "\nchecking *defined* ", '='x50, "\n";
print "Defined\n" if defined $hash{zzz}{uuu};
print "zzz Defined\n" if defined $hash{zzz};
print "zzz,uuu Defined\n" if defined $hash{zzz}{uuu};
print "\nchecking *simple referencing* ", '='x50, "\n";
print "True\n" if $hash{ppp}{qqq};
print "ppp True\n" if $hash{ppp};
print "ppp,qqq True\n" if $hash{ppp}{qqq};
print "\nchecking *values* ", '='x50, "\n";
print "True\n" if values %{$hash{aaa}{bbb}};
print "aaa True\n" if $hash{aaa};
print "aaa,bbb True\n" if $hash{aaa}{bbb};
print "\nchecking *keys* ", '='x50, "\n";
print "True\n" if keys %{$hash{aaa}{bbb}};
print "aaa True\n" if $hash{aaa};
print "aaa,bbb True\n" if $hash{aaa}{bbb};
#end
Regards,
-sm
I am having a lot of difficulty with testing to see if a hash entry is
defined/exists/etc.
I know of the problem of *surprising autovivification* in hash (
http://perldoc.perl.org/functions/exists.html)
but have not been able to find a solution that I can use (Although the
deepest nested array or hash
will not spring into existence just because its existence was tested, any
intervening ones will.)
I was womdering if anyone could help or provide a hind for a satisfactory
workaround.
#### http://perldoc.perl.org/functions/exists.html
#
# exists EXPR
#
# Given an expression that specifies a hash element or array element,
# returns true if the specified element in the hash or array has ever
# been initialized, even if the corresponding value is undefined. The
# element is not autovivified if it doesn't exist.
#
# print "Exists\n" if exists $hash{$key};
# print "Defined\n" if defined $hash{$key};
# print "True\n" if $hash{$key};
#
#
# print "Exists\n" if exists $array[$index];
# print "Defined\n" if defined $array[$index];
# print "True\n" if $array[$index];
#
# A hash or array element can be true only if it's defined, and defined
# if it exists, but the reverse doesn't necessarily hold true.
#
#
# if (exists $ref->{A}->{B}->{$key}) { }
# if (exists $hash{A}{B}{$key}) { }
#
#
# if (exists $ref->{A}->{B}->[$ix]) { }
# if (exists $hash{A}{B}[$ix]) { }
# 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. This happens anywhere
# the arrow operator is used, including even:
#
# undef $ref;
# if (exists $ref->{"Some key"}) { }
# print $ref; # prints HASH(0x80d3d5c)
#
# This surprising autovivification in what does not at first--or
# even second--glance appear to be an lvalue context may be fixed
# in a future release.
#
########################################################################
##
## This is true for *exists*, *defined* and a simple referencing
## of a hash that any of these will cause the
## *surprising autovivification*
print "\n\n", '#'x8, ' HASH behavior ', '#'x20, "\n";
print "\nchecking *exists* ", '='x50, "\n";
print "Exists\n" if exists $hash{xxx}{kkk};
print "xxx Exists\n" if exists $hash{xxx};
print "xxx,kkk Exists\n" if exists $hash{xxx}{kkk};
print "\nchecking *defined* ", '='x50, "\n";
print "Defined\n" if defined $hash{zzz}{uuu};
print "zzz Defined\n" if defined $hash{zzz};
print "zzz,uuu Defined\n" if defined $hash{zzz}{uuu};
print "\nchecking *simple referencing* ", '='x50, "\n";
print "True\n" if $hash{ppp}{qqq};
print "ppp True\n" if $hash{ppp};
print "ppp,qqq True\n" if $hash{ppp}{qqq};
print "\nchecking *values* ", '='x50, "\n";
print "True\n" if values %{$hash{aaa}{bbb}};
print "aaa True\n" if $hash{aaa};
print "aaa,bbb True\n" if $hash{aaa}{bbb};
print "\nchecking *keys* ", '='x50, "\n";
print "True\n" if keys %{$hash{aaa}{bbb}};
print "aaa True\n" if $hash{aaa};
print "aaa,bbb True\n" if $hash{aaa}{bbb};
#end
Regards,
-sm