What's the difference between exists and defined?

Perl

Perl Problem Overview


What is the difference between

if (defined $hash{$key}) { }

and

if (exists $hash{$key}) { }

When do I know which to use?

Perl Solutions


Solution 1 - Perl

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:

  1. It more accurately represents the intent (only the keys are meaningful, not the values).
  2. All undef values share a single allocation (which saves memory).
  3. 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).

Solution 2 - Perl

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

Solution 3 - Perl

Perl documentation:

> When used on a hash element, defined tells > you whether the value is defined, not > whether the key exists in the hash. > Use exists for the latter purpose.

Solution 4 - Perl

As stated in the perldoc on exists:

> Given an expression that specifies an element of a hash, returns true if the specified element in the hash has ever been initialized, even if the corresponding value is undefined.
> > A hash or array element can be true only if it's defined and defined only if it exists, but the reverse doesn't necessarily hold true.

That is, a hash can contain an undefined element, and if that is the case, the defined-check will return false, whereas the exists-check will return true.

Therefore, you should use exists if you wish to know if a given entry exists in the hash, and defined if you wish to know if the given entry exists and is defined.

Solution 5 - Perl

This example shows the difference. In general defined works for any structure and exist is related to hashes.

my %hash=("1"=>undef);
print "exists:".exists($hash{"1"})."\n";
print "defined:".defined($hash{"1"})."\n";

The difference is small and not so obvious, so expect that people will mess with it.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSandra SchlichtingView Question on Stackoverflow
Solution 1 - PerlMichael CarmanView Answer on Stackoverflow
Solution 2 - PerlTLPView Answer on Stackoverflow
Solution 3 - PerlIgorView Answer on Stackoverflow
Solution 4 - PerlSebastian Paaske TørholmView Answer on Stackoverflow
Solution 5 - PerlweismatView Answer on Stackoverflow