Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Re^3: How to determine if an array contains an undef value?

by sundialsvc4 (Abbot)
on Jan 05, 2015 at 13:46 UTC ( #1112194=note: print w/replies, xml ) Need Help??


in reply to Re^2: How to determine if an array contains an undef value?
in thread How to determine if an array contains an undef value?

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.

  • Comment on Re^3: How to determine if an array contains an undef value?

Replies are listed 'Best First'.
Re^4: How to determine if an array contains an undef value?
by Laurent_R (Canon) on Jan 05, 2015 at 22:11 UTC
    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.

      If $val is undef the loop ends
      $ perl -MO=Deparse -le " while (my $val = shift @array) { print $val } + " BEGIN { $/ = "\n"; $\ = "\n"; } while (my $val = shift @array) { do { print $val }; } -e syntax OK

      $error_count++ and next if some_condition();

      Comma to the rescue

      $error_count++, next if some_condition();
        If $val is undef the loop ends
        Yes, right (++), although there are many cases where you know this can't happen. But you are absolutely correct, $val may also be "0" or "", and that is more common. This syntax is broken or at best very dangerous. Which is the reason, BTW, why I would rather use the syntax of first example above, which does not have this problem. I've just corrected my post to strike out this example. Thanks for calling my attention on this.

        Comma to the rescue
        Yes, thanks, I know you can do that, I was just trying to give an example of a stupid mistake I did 4 or 5 years ago when trying to be too clever.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1112194]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (8)
As of 2020-01-17 19:30 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Notices?