Subject: | Can't find 0 (zero) in list |
Date: | Thu, 24 Apr 2008 12:50:28 -0700 (PDT) |
To: | bug-List-Member [...] rt.cpan.org |
From: | Johanus Dagius <jdagius [...] yahoo.com> |
Hello,
I recently tried to use List::Member to find scalar numbers in a list and found that it couldn't find 0 because of its Boolean false property.
For example:
use strict;
use List::Member;
my @list=(0,1,2,3);
print member(0,@list);
produces this error message:
"No target in member/2 at tmem.pl line 4"
The nice brethren at PerlMonks provided this further insight (Wisdom#682389):
(yes, I know about List::Member, but it won't find 0 (zero) in a list, (bug?)
"Yes, there is a bug and you should file a bug. Be sure to CC the author because not all CPAN authors look at their RT queue.
The issue is from this line in the source:
my $target = shift or Carp::croak "No target in member/2 ";
[download]
It assumes that $target will be true - which rules out '', "0", 0, etc. That sub would probably be better written as:
sub member { my ($target, @list) = @_; Carp::croak "No target in member/2 " if ! @list; if (defined $target) { for (0 .. $#list) { return $_ if $list[$_] eq $target; } return $NEG; } else { for (0 .. $#item) { return $_ if ! defined $item[$_]; } return $NEG; } }
[download]
It would also be nice if the documentation explicitly reminded the user that since it returns the index (first item = 0), member() should not be used as a boolean.
L~R "
With the monks' help I wrote this workaround for List::Member, which returns the one-based index of the item if found, or zero if not found, and correctly processes boolean values:
sub member
{
my $item = shift;
my ($found) = grep $_[$_] eq "$item", 0..$#_;
if (defined $found)
{
return $found + 1;
}
else
{
return 0;
}
} ## end member()
---------------------------------
Be a better friend, newshound, and know-it-all with Yahoo! Mobile. Try it now.