When i run this code with a file containing 15 lines, it is returning true for every line. By definition of flip flop operator, it should first evaluate its left operand. If it is true, then it should keep returning the operator true until the right operand is true. In my code, shouldn't the left operand be true for the first line of the input file, then it should keep returning operator true till the fourth line and then stop? Why is it returning true for all 15 lines.

It is false as long as its left operand is false. Once the left operand is true, the range operator stays true until the right operand is true, AFTER which the range operator becomes false again. It doesn't become false till the next time the range operator is evaluated. It can test the right operand and become false on the same evaluation it became true (as in awk), but it still returns true once. If you don't want it to test the right operand until the next evaluation, as in sed, just use three dots ("...") instead of two. In all other regards, "..." behaves just like ".." does.

it is not strange at all. The flip-flop operator is false as long as its left operand is false. Once the left operand is true, the range operator stays true until the right operand is true, after which the range operator becomes false again.

So if you give a true expression on the left side, the flip-flop will be true until after the right hand has become true.

Take this example one-liner:

Code

$ perl -E ' my @a = qw /one two three four five/; for (@a) {say if /wo/../ou/};' two three four

When the "for" loop processes "two", the left-hand regex becomes true, the flip-flop operator becomes true and the programm prints it, as well as the following strings. When the right-hand operator becomes true (four), the flip-flop be comes false, but only the evaluation. So four is printed, the operator becomes false, and five is not printed.

It very strange that the original code does not give the same result. Here is the original code and result with my data. I believe that this verifies the original statement of the problem. Can you explain the difference?

Hi Bill, yes, I agree the OP code is puzzling. But removing the assignment as I suggested in the first place is the right thing to do and would solve the OP's problem. (As a side note, using a $a or $b variable is not a very good idea, because of their special meaning, that's why I changed it to $c in my code below.)

I tried to deparse your code but did not see anything suspicious. Deparsing further down to AST and opcodes might probably help, but I am not really able to understand the output.

I think it might be a precedence issue: because of the parens around the assignment, the conditional might really be interpreted as if the "if" condition was:

Code

if (($a=1)) {

i.e. in effect dropping the rest of the condition.

I tried to modify your code as follows (removing the parens around the assignment) :

So precedence might be a track to follow, but I am at best half-convinced, and I don't see very much how to further explore it.

The other (much less likely) possibility I was thinking of was that, perhaps, the peculiar syntax with the assignment within the parens was somehow forcing a list context to the ".." operator, so that it would act as a range operator and not as a flip-flop operator. A 1..4 range would obviously always be true, but I just can't see how this would possibly happen. I am just mentionning this as a very remote possibility, just in case someone has an idea based on that, but I don't believe this to be even mildly plausible at this point. And the additional problem is that I can't think about a test enabling us to prove or disprove that.

Well, not sure this post is very useful, but at least a couple of ideas to ponder on.