What is the difference between defined and defined?

What's the difference between

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

and

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

When do I know what to use?

+47
perl
Jun 30 '11 at 12:17
source share
5 answers

This is well documented in perldoc entries for defined and exists . Here is a brief summary:

defined $hash{key} indicates whether a value is defined for a given key (ie, 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} indicates whether or not %hash contains the given key. Use it to distinguish between undefined and nonexistent values.

This is easiest to see with an example. Given this hash:

 my %hash = (a => 1, b => 0, c => undef); 

Here are the results of a search, definition, 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 only if ($hash{key}) {...} , because (in many common cases) only true values ​​are significant / possible. If the false values ​​are valid, you must add defined() to the test. exists() used much less frequently. The most common case is probably when using a hash as a set. eg.

 my %set = map { $_ => undef } 'a' .. 'z'; 

Using undef for given values ​​has several advantages:

  • This more accurately represents intent (only keys make sense, not meanings).
  • All undef values ​​share a single allocation (which saves memory).
  • exists() tests are slightly faster (because Perl does not need to retrieve the value, but only determine what it is).

It also has the disadvantage that you must use exists() to verify membership in a set, which requires more typing and will do the wrong thing if you forget it.

Another place where exists is useful is to examine locked hashes before trying to retrieve a value (which will throw an exception).

+74
Jun 30 2018-11-11T00:
source share

defined checks the value of a variable; exists checks if it was previously declared / initialized. If it exists, simple and simple.

eg:.

 $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 
+14
Jun 30 '11 at 12:37
source share

Perl documentation :

When using a hash element, it is determined whether you determine the value and whether the key exists in the hash. Use exists for the latter purpose.

+5
Jun 30 '11 at 12:37
source share

As pointed out in perldoc on exists :

Given an expression that indicates a hash element, returns true if the specified element in the hash has never been initialized, even if the corresponding value is undefined.

A hash or array element can be true only if it is defined and defined only if it exists, but the converse is not necessarily true.

That is, the hash may contain an undefined element, and if so, defined -check will return false , whereas exists -check will return true .

Therefore, you must use exists if you want to know if a given entry exists in the hash, and defined if you want to know if this entry exists and which is defined.

+4
Jun 30 '11 at 12:20
source share

This example shows the difference. In general, certain works for any structure and exist associated with 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 people to mess with it.

+3
Jun 30 '11 at 12:30
source share



All Articles