What is the difference between
if (defined $hash{$key}) { }
and
if (exists $hash{$key}) { }
When do I know which to use?
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.
The exists() function in Perl is used to check whether an element in an given array or hash exists or not. This function returns 1 if the desired element is present in the given array or hash else returns 0. Parameters: Expression : This expression is either array or hash on which exists function is to be called.
From perldoc perldata: If you evaluate a hash in scalar context, it returns false if the hash is empty. If there are any key/value pairs, it returns true; more precisely, the value returned is a string consisting of the number of used buckets and the number of allocated buckets, separated by a slash.
This is well-documented in the perldoc entries for defined
and exists
. Here's a quick summary:
defined $hash{key}
tells you whether or not the value for the given key is defined (i.e. not undef
). Use it to distinguish between undefined values and values that are false in a boolean context such as 0
and ''
.
exists $hash{key}
tells you whether or not %hash
contains the given key. Use it to distinguish between undefined values and non-existent ones.
This is easiest to see with an example. Given this hash:
my %hash = (a => 1, b => 0, c => undef);
Here are the results for retrieval, defined-ness, and existence:
# key value defined exists a 1 1 1 b 0 1 1 c undef 0 1 d undef 0 0
In practice, people often write just if ($hash{key}) {...}
because (in many common cases) only true values are meaningful/possible. If false values are valid you must add defined()
to the test. exists()
is used much less often. The most common case is probably when using a hash as a set. e.g.
my %set = map { $_ => undef } 'a' .. 'z';
Using undef
for set values has a few advantages:
undef
values share a single allocation (which saves memory).exists()
tests are slightly faster (because Perl doesn't have to retrieve the value, only determine that there is one).It also has the disadvantage that you have to use exists()
to check for set membership, which requires more typing and will do the wrong thing if you forget it.
Another place where exists
is useful is to probe locked hashes before attempting to retrieve a value (which would trigger an exception).
defined
checks the value of the variable, exists
checks if it has been previously declared/initialized. If it exists, plain and simple.
E.g.:
$hash{$key} = undef; # various return values: exists $hash{$key}; # true defined $hash{$key}; # false $hash{$key}; # false $hash{$key} = 0; # various return values: exists $hash{$key}; # true defined $hash{$key}; # true $hash{$key}; # false exists $hash{$foo}; # false
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