Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is List::MoreUtils::none buggy?

Tags:

list

perl

I think none subroutine from List::MoreUtils does not act as described. According to documentation,

none BLOCK LIST Logically the negation of any. Returns a true value if no item in LIST meets the criterion given through BLOCK, or if LIST is empty. Sets $_ for each item in LIST in turn

Now, try:

use strict;
use warnings;
use 5.012;
use List::MoreUtils qw(none);

my @arr = ( 1, 2, 3 );
if ( none { $_ == 5 } @arr ) {
    say "none of the elements in arr equals 5";
}
else {
    say "some element in arr equals 5";
}

works OK, but replace @arr with an empty one (my @arr = (); or simply my @arr;) and you get a wrong answer.

What's going on?

update: i had List::MoreUtils ver 0.22. Updated to the latest and it seems OK. Weird though!

like image 744
David B Avatar asked Aug 24 '11 13:08

David B


1 Answers

The documentation is in line with the v 0.33 pure Perl implementation. The reason why it failed was because the implementation changed between versions 0.22 and 0.33.

In v 0.33, if @array is empty, the for loop will not execute, so YES will be returned.

Here are the two versions side-by-side:

# v 0.33                      |  # v 0.22
------------------------------+----------------------------------------
sub none (&@) {               |  sub none (&@) {
    my $f = shift;            |      my $f = shift;
    foreach ( @_ ) {          |      return if ! @_;          # root cause
        return NO if $f->();  |      for (@_) {
    }                         |          return 0 if $f->();
    return YES;               |      }
}                             |      return 1;
                              |  }

MetaCPAN also provides a comprehensive diff between versions 0.22 and 0.33

like image 192
Zaid Avatar answered Nov 06 '22 19:11

Zaid