Pete Emerson wrote:
> Thanks for your code, I've gotta look up \Q to make sure I understand
> what's happening, but it looks great. I'm still parsing your comments
> to make sure I understand everything.

Within a string, \Q escapes (with '\') all following non-word characters
(a-z, A-Z, 0-9 and underscore) until a subsequent \E switches off the
escaping. It is equivalent to the built-in function 'quotemeta', which
does the same thing to its parameter and returns the result. It's a way
of making sure that a variable that you're using within a regex doesn't
have any unescaped metacharacters causing trouble.

> I'm not quite sure what you meant about side effects from my
> conditional being frowned upon...how else do you use the () ? () : ()
> conditional, which I just consider a shortcut for if () { } else { }
> ? What do you mean by "side-effects"?

A side-effect is any change that an expression might make when it is
being evaluated. It becomes a command rather than simply an
expression, and should be controlled by a control-flow statement if
rather than an operator like ? .. : . For instance:

    for my $i ( 1 .. 6) {
        printf "%d blind %s\n", $i, $i == 1 ? 'mouse' : 'mice';
    }

is fine as as expressions 'mouse' and 'mice' don't do anything: the
conditional operator is being used for its result rather than for
the consequences of what its operands happen to do. In your code,
you write

    $string=~/$match/ ? next : ($success = 0);

which is an expression trying to return the value of one or
other operand 'next' or '$success = 0' except that in the former
case it doesn't get a chance because the 'next' takes control
from it. In the absence of anything to do with the result it simply
gets thrown away. This isn't a problem in this situation as it's
not gone to great lengths to produce it for you, but it could
feasibly involve database or Internet accesses or something
equally weighty which were totally unnecessary.

Use it as you would any other operator and you're on the right
lines. I doubt if you'd be writing:

    for (1..3) {
        (print 'abc') + ($success = 0) + (last);
    }


just to get it to do all three? That's doing a similar thing with
the addition operator instead of the conditional operator:
all of the operands are evaluated in sequence and the result
of the additions is thrown away.

Summarily:

1/ the conditional operator isn't a shorthand for anything, it's
meant to evaluate to one of two values depending on the
the truth of a condition.
2/ If you want to perform actions according to a condition
use 'if'.
3/ Make your code say what it is you're doing rather than bending
construct to achieve something they weren't designed for.

> I disagree (cautiously) with you about my use of 'last'. If the string
> does not match $match, then the 'next' is not called, therefore the
> 'last' is called and the loop exits, instead of going back and
> checking $string on the next $match.

You're absolutely right, the last /is/ required! I failed to see the
'next' operand in your conditional operator and then confused
the 'last' with a 'next' because I expected there to be one
somewhere. This sort of thing happens to me from time to
time depending on the prevailing wind direction. However,
using a 'next', because it doesn't even have a value, is a still
more awful thing to do here than the $success = 0 which I did see!

You could still write this using the comma operator as well, like this:

($string=~/$match/) ? 42 : ($success=0, last);

> Run the code with this extra  print statement, and note that on
> the third time through the list, the inner foreach loop exits after
> the first iteration:
>
> #!/usr/bin/perl -w
>
> use strict;
> my @strings=qw(onetwothree threeonetwo nothing);
> my @matches=qw(one two three);
> foreach my $string (@strings) {
>     my $success=1;
>     foreach my $match (@matches) {
>         print "looping\n";
>         ($string=~/$match/) ? (next) : ($success=0);
>         last;
>     }
>     ($success) ? (print "$string matches.\n") : (print "$string does
> not match.\n");
> }

I hope this helps. Come back if you have any further questions.

Cheers,

Rob




-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to