defined#
Test whether a value, variable, or subroutine is defined.
defined returns true when EXPR holds any value other than the
undefined value undef, and false when it holds undef. It is the
one and only way to tell undef apart from the other false values
(0, "", "0"), which a plain boolean test cannot.
Synopsis#
defined EXPR
defined
defined &SUBROUTINE
What you get back#
A boolean: true if EXPR is defined, false if it is undef.
With no argument, defined operates on $_.
The result is context-sensitive only in the usual boolean sense;
defined does not propagate list context into EXPR.
Why it exists, and why a plain boolean is not enough#
Many operations return undef to signal failure, end of file, a
system error, an uninitialised variable, or some other exceptional
condition. defined lets you distinguish that sentinel from a
legitimate result. A simple boolean test treats undef, 0, "",
and "0" the same — all four are false — so you cannot use truthiness
to tell “nothing was returned” apart from “zero was returned”:
my $n = some_count();
if ($n) { ... } # false for 0 AND for undef
if (defined $n) { ... } # false only for undef
Note that undef is itself a valid scalar value. Its presence does
not necessarily mean something went wrong: pop @empty returns
undef, but so does pop @array when the element popped happened
itself to be undef. defined tells you the value is undef; it
does not tell you why.
Default argument: $_#
With no argument, defined tests $_:
while (<$fh>) {
next unless defined; # same as: defined $_
chomp;
...
}
defined &subroutine#
defined &func asks whether subroutine func has ever been defined.
A forward declaration (sub func;) does not make it defined; an
actual body does:
sub greet { "hello" }
print defined &greet ? "yes\n" : "no\n"; # yes
print defined &missing ? "yes\n" : "no\n"; # no
A subroutine that is not defined may still be callable: the
package’s AUTOLOAD method can bring it into existence on first
call. defined &func reflects the current state of the symbol
table, not what a future AUTOLOAD might produce. See perlsub.
The return value is unaffected by forward declarations.
Hash elements: defined vs exists#
On a hash element, defined asks about the value, not the key:
my %h = (a => 1, b => undef);
print exists $h{a} ? 1 : 0, "\n"; # 1
print defined $h{a} ? 1 : 0, "\n"; # 1
print exists $h{b} ? 1 : 0, "\n"; # 1 — key is present
print defined $h{b} ? 1 : 0, "\n"; # 0 — value is undef
print exists $h{c} ? 1 : 0, "\n"; # 0 — key not present
print defined $h{c} ? 1 : 0, "\n"; # 0 — also autovivifies? no, rvalue is safe
Use exists to ask “is this key in the hash?” and defined to ask
“does this slot hold a usable value?”. The two differ whenever a
value was explicitly assigned undef or left undef by construction
(e.g. $h{b} = undef, or @h{qw(a b c)} = (1)).
The same distinction applies to array elements: exists $a[7]
reports whether the array is long enough and the slot has been
assigned, while defined $a[7] reports whether that slot currently
holds a non-undef value.
Examples#
The common pop-until-empty idiom — stops only when the array is
exhausted, not on a legitimate falsy element:
while (defined(my $val = pop @ary)) {
process($val);
}
Check a system call for failure:
my $target = readlink $sym;
die "can't readlink $sym: $!" unless defined $target;
Call a coderef only if one was supplied:
sub dispatch {
my ($cb, @args) = @_;
return defined &$cb ? $cb->(@args) : die "no callback";
}
Provide a default without clobbering a legitimate 0 or "":
$debugging = 0 unless defined $debugging;
The modern form is the defined-or operator //, which does exactly
this test inline:
$debugging //= 0;
my $name = $user // "anonymous";
Regex capture: $1 being defined tells you the capture group
participated in the match, even if it matched the empty string:
"ab" =~ /a(.*)b/;
print defined $1 ? "matched '$1'\n" : "no match\n"; # matched ''
Aggregates: defined @array, defined %hash are no longer supported#
Historically defined @array and defined %hash reported whether
memory for the aggregate had ever been allocated — an implementation
detail that was rarely what callers actually wanted. Modern Perl
rejects these forms. Test the aggregate’s size instead:
if (@array) { print "array has elements\n" }
if (%hash) { print "hash has members\n" }
In boolean context an array evaluates to its element count and a hash evaluates to a true value iff it has any keys. That is the test you almost always wanted.
Testing an element of an aggregate is still fine and is the usual
use: defined $array[$i], defined $hash{$key}.
Overuse#
defined is frequently overused. Zero and the empty string are
defined values. A regex match that captures zero characters still
sets $1 to a defined empty string — the match did not fail; it
matched something that happened to be of length zero. When a
function returns undef, it is admitting it cannot give you a
meaningful answer. Reach for defined when you are questioning the
integrity of a value. For “is it zero?” or “is it empty?” a plain
comparison to 0 or "" is what you want.
Edge cases#
Bare
definedwith no argument tests$_. Insidemap,grep, or awhile (<$fh>)loop this is the idiomatic form.defined(&func)vsdefined(&{$ref}): both work. The second dereferences a code reference and asks whether the referenced slot currently holds a defined subroutine body.defined $hash{$key}does not autovivify the key —definedis an rvalue context and leaves the hash unchanged. Contrast with$hash{$key}{inner} = 1, which does autovivify.Chained hash/array access:
defined $h{a}{b}autovivifies$h{a}into an empty hash ref in order to perform the inner lookup, even though the outerdefinedreads the result. This is a consequence of how the dereference chain is evaluated, not ofdefineditself. To probe nested structure without autovivifying, check each level withexistsfirst.defined $&,defined $1: after a successful match these are defined; after a failed match they retain whatever value they had from the previous successful match in the same scope.definedalone is not a safe “did the match succeed” test — check the match operator’s return value instead.definedis not an lvalue.defined $x = $yis a syntax error; parenthesise the assignment:defined($x = $y).
Differences from upstream#
Fully compatible with upstream Perl 5.42.
See also#
undef— the valuedefinedtests against, and the operator that produces or clears itexists— ask whether a hash key or array index is present, independent of whether its value isundefref— when the question is not “is it defined” but “what kind of reference is this”//and//=— defined-or operator; the modern inline form ofdefined($x) ? $x : $default$_— the default argument whendefinedis called with no expression