in reply to Re^6: Why does exists cause autovivication?
in thread Why does exists cause autovivication?
Exists checks to see that the lookup of $var->{$key} is successful, meaning that $key has been used to store a value in the hash prior to the check. Thus we have:
# $user_by_uid{$uid}->{$host} $var= $user_by_uid{$uid} $key= $host
What this means is that if the result of $user_by_uid{$uid} is undef (either by having an explicit undef value or by not being in the %user_by_uid hash at all) then it is autovivified. If there is a hash reference stored in $user_by_uid{$uid} (either intentionally or via autoviv) then the it is checked to see if $host had ever been used as a key.
Tring to reduce this to a one liner: exists checks the the last hash lookup you feed it, not if the full "path" through the data structure exists. This is more obvious if you consider $user_by_id[$uid]->{$host}, obviously exists doesnt operate on arrays, and we get no error, so it means that only ->{$host} part is relevent to exists.
You could always write a simple routine:
sub my_exists { my ($hash_ref,$key)= @_; return $hash_ref and exists $hash_ref->{$key} }
which would not autovivify. Compare it to how the real thing *might* be coded. Im pretty sure this actually wont work due to some subtleties of hash lookups and lvalue arguments but its pretty close to the real thing.
sub my_fake_exists { my ($hash_ref,$key)=@_; $hash_ref={} if not defined $hash_ref; #fake autoviv return exists $hash_ref->{$key}; # do the lookup }
$world=~s/war/peace/g
|
---|
Replies are listed 'Best First'. | |
---|---|
Re^8: Why does exists cause autovivication?
by Argel (Prior) on Jan 02, 2008 at 20:45 UTC | |
by shmem (Chancellor) on Jan 02, 2008 at 21:31 UTC |