Misc

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 defined with no argument tests $_. Inside map, grep, or a while (<$fh>) loop this is the idiomatic form.

  • defined(&func) vs defined(&{$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 keydefined is 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 outer defined reads the result. This is a consequence of how the dereference chain is evaluated, not of defined itself. To probe nested structure without autovivifying, check each level with exists first.

  • 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. defined alone is not a safe “did the match succeed” test — check the match operator’s return value instead.

  • defined is not an lvalue. defined $x = $y is a syntax error; parenthesise the assignment: defined($x = $y).

Differences from upstream#

Fully compatible with upstream Perl 5.42.

See also#

  • undef — the value defined tests against, and the operator that produces or clears it

  • exists — ask whether a hash key or array index is present, independent of whether its value is undef

  • ref — when the question is not “is it defined” but “what kind of reference is this”

  • // and //= — defined-or operator; the modern inline form of defined($x) ? $x : $default

  • $_ — the default argument when defined is called with no expression