deprecated has asked for the wisdom of the Perl Monks concerning the following question:

(/me dons suit of --proof armor)

I'm trying to validate user input against an array or ignore it in a catchall function.

We just recently had a discussion about reinventing the wheel, and this strikes me as something that's reinvented often. However, I wasnt able to find anything quickly using the search, so I hacked this together:

sub getline { my $line; chomp ($line = <>); if (@_) { my $bool; foreach (@_) { if ($line =~ /$_/) { undef $bool } else { $bool++ } } return $bool ? $line : 0 ; } $line; # we got here because caller didnt care about what they get. }
I interpret this as "get a line from STDIN. if caller gave us an array, we check it against all the elements of the array and set a false value if it doesnt check out. if we have false at the end of the loop, we return false. otherwise we return what we got. if we didnt get an array, we return what we got from STDIN."

The problem with this is the code doesnt work. Rather, it does, but its too fascist. If I pass qw(foo bar baz bletch) and my user gives me "foo bletch" I want to accept it. I get the feeling here that I am forgetting something that is criminally stupid.

Shaking my head,
brother dep.

--
transcending "coolness" is what makes us cool.

Replies are listed 'Best First'.
Re: Validating User Input
by mirod (Canon) on Feb 18, 2001 at 14:42 UTC

    Here is how I understand your question:

    if getline is called with qw(foo bar baz bletch) you want:
    - foo bar to be OK,
    - toto tutu to be NOT OK,
    - foo bar toto to be NOT OK,
    - foo foo to be OK,
    - an empty input to be OK.

    sub getline { return unless @_; # caller don't want + checks my %valid_word= map { ( $_, 1) } @_; # create a hash val +id_word => 1 my $line; chomp( $line = <>); my @word= split /\s/, $line; foreach my $word (@word) { return undef unless $valid_word{$word}; } # return failure as + soon as a a bad word is found return $line; }

    Note that if you want to allow empty input lines you will have to test the result for undef, otherwise you can return 0 on failure or empty lines.

Re: Validating User Input
by chipmunk (Parson) on Feb 19, 2001 at 00:28 UTC
    It appears in your code that you set $bool to undef if the regex does match. Do the elements in @_ describe input that you want to keep, or that you want to reject?

    In any case, your code will accept or reject based only on the last element of @_. If the regex matches, $bool will be undef, and if the regex doesn't match, $bool will be true, regardless of how all the previous regexes turned out.

    As soon as you know you want to accept/reject input, you should last out of the loop. For example:

    sub getline { my $line = <>; chomp $line; if (@_) { my $reject; for (@_) { if ($line =~ /$_/) { $reject = 1; last; } } $line = undef if $reject; } return $line; }