in reply to Re: grep trouble
in thread grep trouble

I wanted to address a few of your points. I intended to do so earlier, but just didn't have the time until now.

  1. You mentioned that using $_ to hold a pattern is bad style. But he's using grep. If he's passing patterns to grep what choice does he have? Remember: my @found = grep { do something with $_ } @input_list;. If he really intended grep { $something =~ m/$_/ } @array; do you know of some other way to use grep that wouldn't involve $_?

    Your sub-item (a): The default behavior of the m// operator is to match against $_, but he didn't invoke its default behavior.

    Sub item (b): Yup... but not in this case.

  2. That's a better question: Why is he using an empty string as the pattern in a regexp? Additionally, why would he be interested in matching an empty pattern against an empty string literal. But I have a feeling that's not the whole story. His input list to grep probably consists of a lot of patterns, which may include an empty string. Why is he matching against the literal empty string? That's again probably just a boiled down example of the problem. I suspect that where he showed us a literal empty string, there's probably a foreach loop with an iterator on the lefthand side of the match operator, as in the following snippet:

    my @patterns = ( .................. ); foreach my $iterator ( @array ) { my @found = grep { $iterator =~ m/$_/ } @patterns; do_something_with( @found ); }

    You make a good point that the behavior of a m// (empty pattern match) is impossible to intuitively predict. Though the behavior may be useful in some situations, those situations probably warrant a comment in real-world code so that it doesn't initiate a head-scratching and document-reading session when someone looks at the code six months later. Regardless of whether the feature is generally familiar to people, it seems to be accurately documented. It might be a dusty corner in the halls of pattern matching, but Perl is full of dusty corners that provide useful features when nothing else would be quite as convenient.


Dave

Replies are listed 'Best First'.
Re^3: grep trouble
by LanX (Saint) on Apr 18, 2011 at 08:30 UTC
    1. > But he's using grep.

    Agreed, but he could copy $_ and define fall-backs for edge cases like "". (I'm not sure if he should)

    grep { my $pat = ( $_ eq ="" ? EMPTY_PAT : $_ ); $string =~ m/$pat/g } @patterns;

    If this gets more complicated he should consider using a function instead of an anonymous block.

    2. > I suspect that where he showed us a literal empty string, ...

    I suppose he is checking multiple log-files simultaneously for the same matching patterns. By grepping patterns, he is calculating the intersection of all patterns which apply to all files.

    > those situations probably warrant a comment in real-world code

    That's why I would prefer a special var $PATTERN for this behavior.

    Cheers Rolf

    UPDATE: what bothers me is not this special behavior of a literally empty match m// but that of "If the PATTERN evaluates to the empty string". IMHO that $pat="";m/$pat/ behavior is difficult to justify.

Re^3: grep trouble
by LogMiner (Novice) on Apr 19, 2011 at 01:09 UTC
    > I'm still not sure what you're trying to achieve here, cause your grep returns the PATTERNs which matched.

    Yes, LanX, and in scalar context it returns the NUMBER of patterns that matched. That's what I'm using in my (much larger) script.

    > ...His input list to grep probably consists of a lot of patterns, which may include an empty string. ... where he showed us a literal empty string, there's probably a foreach loop with an iterator on the lefthand side of the match operator...

    That's exactly what I'm doing, davido.

    Obviously, if I posted a (much larger) block of real-life code here, it would make more sense (to those who bother comprehending it), but there would be much fewer interested people. A short, distilled version of the problem may not make real-life sense, but is much easier to discuss.

      That's the right strategy; post a minimal snippet that still demonstrates the problem. May have helped the curious if the original question mentioned 'this is a boiled down snippet' or something like that. Even though it's absolutely what people should be doing, the reality is that way too often we see some completely irrelevant code, or an entire script with no attempt to isolate the problem. Your post was great, and it motivated me to dig into the Perl docs. Any post that intrigues me enough to dig into the documentation again deserves a ++.


      Dave