in reply to How to determine if an array contains an undef value?

By the way, in addition to the answers already given, a common pitfall:

sub foo { return } sub bar { return undef } my $a = foo(); # $x is undef, if($x) is false my @b = foo(); # @b is empty, if(@b) is false my $c = bar(); # $c is undef, if($c) is false my @d = bar(); # @d is (undef), if(@d) is true!!

because a return with no arguments is context-sensitive.

Replies are listed 'Best First'.
Re^2: How to determine if an array contains an undef value
by Anonymous Monk on Jan 04, 2015 at 18:22 UTC

    Oops, obviously s/\$x/\$a/g

Re^2: How to determine if an array contains an undef value?
by thanos1983 (Parson) on Jan 04, 2015 at 22:31 UTC

    Hello Anonymous Monk,

    Thank you for your input, this is an interesting observation.

    Seeking for Perl wisdom...on the process of learning...not there...yet!

      That observation might be extended to say ... “be careful of simple-tests for ‘falseness,’ if there are several different kinds of ‘falseness’ that you actually need to distinguish.”   Explicitly test for things using exists(), defined(), and so on.   Actually, I customarily test explicitly for every explicit that I expect to see, and cause the program to die() if it falls through all of the cases.   Tests for the “falseness” of the return-value are used in my code only when the value is 1 or 0.   The program catches a lot of its own bugs this way ... especially a concern in a typeless language like Perl.

        Tests for the “falseness” of the return-value are used in my code only when the value is 1 or 0.
        I more or less agree with the rest of what you are saying, but I do not agree with that. It is perfectly legitimate, Perlish and idiomatic to evaluate an array in scalar/boolean context to figure out if it is empty. The scalar return value may be 0 (the array is empty) or 1, 2, 3, ..., any positive integer other than 0 (the array is not empty). For example:
        while (@array) { my $val = shift @array; # do something with $val }
        or possibly:
        while (my $val = shift @array) { # ... }
        or:
        if (length $string) { # ... }
        (but not if ($string), because that might not give the expected result with the string "0"). Or you could have a sub return undef (false) if it did not succeed, or a hash or array reference (something that is always true), or even a simple array or hash, if it did succeed.

        Similarly, if you open a file with this idiomatic syntax:

        open my $fh, "<", $file or die "failed to open $file $!";
        you're not testing for 0 or 1, and yet it works perfectly and is considered to be a best practice.

        Of course, you've gotta know what you're doing and should probably try not to be too clever. I once got bitten by something like this:

        $error_count++ and next if some_condition();
        which did not work correctly the first time through the loop, because $error_count was 0 (or undef, whatever it was, I don't remember, it happened some years ago). While:
        ++$error_count and next if some_condition();
        would have worked fine, I was probably trying at the time to be a little bit too clever (and too concise).

        Limiting boolean tests to only 0 and 1 values is taking off a lot of Perl's expressive power.

        Update: crossed out one example after the comment below from Anonymous Monk.