Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between exists and defined?

Tags:

perl

What is the difference between

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

and

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

When do I know which to use?

like image 647
Sandra Schlichting Avatar asked Jun 30 '11 12:06

Sandra Schlichting


People also ask

What does defined mean in Perl?

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.

How do I use exists in Perl?

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.

How do I check if a Perl hash is empty?

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.


2 Answers

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).

like image 167
Michael Carman Avatar answered Sep 28 '22 09:09

Michael Carman


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 
like image 31
TLP Avatar answered Sep 28 '22 09:09

TLP