In Perl, what's the difference between "if defined $count" and "if $count"?

I have the following script:

use warnings;
use strict;

my $count = 0; 
my ( @first , @second , @third );

while ($count <= 7){

    push ( @first , $count);
    push ( @second , $count) if defined $count;
    push ( @third , $count) if $count;


print "first: @first\n";
print "second: @second\n";
print "third: @third\n";

This produces the following output:

first: 0 1 2 3 4 5 6 7
second: 0 1 2 3 4 5 6 7
third: 1 2 3 4 5 6 7

What's the difference between putting if defined $count vs. if $count, other than the latter method won't add the zero to the array? I've searched the perldocs but couldn't find the answer.


Truth and Falsehood in perlsyn explains what values are considered false in a boolean context:

The number 0, the strings '0' and '', the empty list (), and undef are all false in a boolean context. All other values are true.

undef is the value of a variable that has never been initialized (or that has been reset using the undef function). The defined function returns true if the value of the expression is not undef.

if $count is false if $count is the number 0, the string '0', the empty string, undef, or an object that has been overloaded to return one of those things when used in a boolean context. Otherwise, it's true. (The empty list can't be stored in a scalar variable.)

if defined $count is false only if $count is undef.

if you see the documentation of defined in perldoc then you will find that

  • Returns a Boolean value telling whether EXPR has a value other than the undefined value undef. If EXPR is not present, $_ is checked.

  • A simple Boolean test will not distinguish among undef, zero, the empty string, and "0" , which are all equally false.

that means,

push ( @second , 'undef') if defined $count; 

when $count = 0, then it is defined because 0 is different from undef and defined returns true, but in this case push ( @third , 'undef') if $count; if condition fails, that's why it is not pushing 0 into the array.

The if decides to run its block (or single statement) by looking at the value of the expression you give it:

 if( EXPR ) { ... }

If that expression is true, it runs its block. If that expression is false, it doesn't.

That expression can be just about anything. Perl evaluates the expression, reducing it to a value that is either true or false. The if() then looks at that value.

So, removing that part of your question, you're left with "What's the difference between defined $count and $count". Well, one is the return value for defined and the other is whatever value is stored in $count.

When you want to figure out what a particular bit of code is doing, reduce it in the same logical process that perl would, one step at a time. See what each step does, and you'll often be able to answer your own questions. :)

You say that you searched the documentation, but I'm not sure where you looked. If you want to look up a built-in function, you can use perldoc's -f switch:

 $ perldoc -f defined

If you want to read about Perl's syntax for things such as if, that's in perlsyn.

I have a beginner's guide to the Perl docs in Perl documentation documentation.

The defined predicate tests to see whether the variable ($count in this case) is defined at all. In the code you've written, it always will be defined inside the loop because it's always got some value.

If you were to add:

undef $count;
push ( @first , 'undef'); 
push ( @second , 'undef') if defined $count; 
push ( @third , 'undef') if $count; 

after the loop, you would see the difference. (Note that I changed the code to add the literal 'undef' instead of $count because you'll get misleading effects from adding the actual undef value.

As any fule kno, "The number 0, the strings '0' and '', the empty list (), and undef" should not equate to false because they are not boolean in nature. Writing code that relies on this perversion, while technically correct, is misleading and should be strongly discouraged. As should weeds and sissies.

The way I read it.

if $count is only true when $count evaluates != 0, hence the third array has no 0 in it.

if defined $count checks to see if the $count as a scalar has been created, and as you have $count scalar, it's the same as the first one.

Need Your Help

IItemTransform and existing minified files css transformation bundling-and-minification system.web.optimization

TL;DR: IItemTransform isn't getting executed when a minified file already exists in the same folder as the original (non-minified) file.