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

Monks,

I have this statement in one of my scripts:
foreach (@data){ $count++ if $_ =~ /\b$dst[0]\b/ && /\b$service[0]\b/; }
$dst is always an ip address (this is considered a string correct?) and $service is sometimes numeric (ie. 80) and sometimes a string (ie. http). Am I using && correctly? I only want to count the line if these two matches appear in the same line. Should I be testing if $service is a string or number first?

Thanks in advance for any help.

Replies are listed 'Best First'.
Re: I'm confused with Bitwise Operators
by dws (Chancellor) on Jun 07, 2002 at 21:11 UTC
    Am I using && correctly?

    Consider   $_ =~ /A/ && /B/; and think about whether it is equivalent to   /A/ && /B/The answer depends on the precedence of =~ vs. &&

    Unclear on the precedence? There's an operator precedence table in perlop.

      Something else to consider: "distribution" (or lack thereof) of the binding operator. Note that $_ =~ (/A/ && /B/) is not equivalent to ($_ =~ /A/) && ($_ =~ /B/). The latter is what you would want.

      Regarding the original poster's code:

      $count++ if $_ =~ /\b$dst[0]\b/ && /\b$service[ +0]\b/;
      This works only because $_ is being tested. Taking precedence into consideration (and the fact that m// works on $_ by default), this code is equivalent to
      ($_ =~ /\b$dst[0]\b/) && ($_ =~ /\b$service[+0]\b/);
      If the data were in any other variable ($var, for example), and one just replaced $_ with $var in the OP's code, it would be equivalent to
      ($var =~ /\b$dst[0]\b/) && ($_ =~ /\b$service[+0]\b/);
      which isn't What You Want.

      Just my observations. HTH.

      --

      There are 10 kinds of people -- those that understand binary, and those that don't.

Re: I'm confused with Bitwise Operators
by Zaxo (Archbishop) on Jun 07, 2002 at 20:58 UTC

    Operator && is logical and, not bitwise, which is '&'. Logical && is the correct choice for what you're doing. See perlop for details, but it acts [almost] like the C operator of the same name. The left argument is evaluated. If false, the right argument is ignored and the whole && expression returns false. If the left evaluates true, the right hand argument is evaluated and that result returned.

    Your code is correct as far as perl goes, though the '$_ =~' is unneeded - $_ is the default argument for m//. You will get some surprises, however, when $service[0] is numeric and $_ contains a dotted quad ip matching the service you're looking for. A single regex containing more context is in order, or else perhaps a split to a predictable array.

    Update: Doh! dws is on the money with the operator precedence issue.

    After Compline,
    Zaxo

A reply falls below the community's threshold of quality. You may see it by logging in.