eval within grep not working

Discussion in 'Perl Misc' started by Krishna Chaitanya, Oct 1, 2010.

  1. Hi,

    Am trying the exercise in Chapter 17 of Learning Perl....for those who
    don't have that book, here is the question:

    "Make a program that reads a list of strings from a file, one string
    per line, and then lets the user interactively enter patterns that may
    match some of the strings. For each pattern, the program should tell
    how many strings from the file matched, then which ones those were.
    Don’t reread the file for each new pattern; keep the strings in
    memory. The filename may be hardcoded in the file. If a pattern is
    invalid (for example, if it has unmatched parentheses), the program
    should simply report that error and let the user continue trying
    patterns. When the user enters a blank line instead of a pattern, the
    program should quit."

    I came up with this code:



    use strict;
    use warnings;
    use diagnostics;

    open FH, "abc" or die "Cannot open file: $!\n";
    my @file_contents = <FH>;

    while(1) {
    chomp(my $pattern = <STDIN>);
    last if $pattern =~ /^\s*$/;
    my @matched = grep {
    my $line = $_;
    eval { $line =~ /$pattern/ };
    if ($@) {
    print "Error in pattern : $@\n";
    } @file_contents;
    print "Number of matched lines = ", scalar @matched, "\n";
    print "Matched lines are:\n @matched\n";

    It doesn't work...for simple patterns like "This", "cat", etc. Oh, and
    file "abc" contains:

    This is a cat
    This is a dog
    This is a ball

    But it works if I put the eval outside the grep (as mentioned in the
    solution to the exercise in that book). I thought the code block for
    grep in my code above always returns either true/false......but it's
    not working. Can you pls. help me by pointing out the mistake?

    Am using Perl 5.8.8 on Linux, if it matters.

    Krishna Chaitanya, Oct 1, 2010
    1. Advertisements

  2. Uri Guttman

    Uri Guttman Guest

    >>>>> "KC" == Krishna Chaitanya <> writes:

    KC> my @matched = grep {
    KC> my $line = $_;
    KC> eval { $line =~ /$pattern/ };
    KC> if ($@) {
    KC> print "Error in pattern : $@\n";
    KC> undef;
    KC> }
    KC> } @file_contents;

    your problem is simple. you don't pass the result of the match to
    grep. it is using the last expression evaluated as its boolean (likely
    the if()). so you can do one of two things: save the results of the eval
    and pass that to grep, or eval a qr// to check the regex validity and
    then do the match at the end. here are untested examples:

    my @matched = grep {
    my $line = $_;

    # that isn't needed even though i always used named vars. in this short
    # context, $_ is fine

    my $match = eval { $line =~ /$pattern/ };
    if ($@) {
    print "Error in pattern : $@\n";
    # exit the grep and get another user line. this is what the exercise
    # asks for
    next ;

    } @file_contents;

    # this version also moves the pattern verifyer outside the grep where it
    # belongs. makes the grep short and easy to read as well.

    my $pat = eval { qr/$pattern/ };
    unless( $pat ) {
    print "Error in pattern : $@\n" ;
    next ;

    my @matched = grep /$pat/, @file_contents;


    Uri Guttman ------ -------- http://www.sysarch.com --
    ----- Perl Code Review , Architecture, Development, Training, Support ------
    --------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
    Uri Guttman, Oct 1, 2010
    1. Advertisements

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Eric Newton
    Brock Allen
    Apr 4, 2005
  2. DataBinder.Eval and Eval.

    , Jun 16, 2006, in forum: ASP .Net
    Karl Seguin [MVP]
    Jun 16, 2006
  3. William
    Jan 7, 2006
  4. jeniffer
    John W. Krahn
    Mar 20, 2006
  5. Marc Girod

    to eval or not to eval?

    Marc Girod, Apr 19, 2011, in forum: Perl Misc
    Marc Girod
    Apr 19, 2011

Share This Page