CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Intermediate:
flip flop operator with assignment operator

 



iThunder
Novice

Sep 26, 2014, 12:09 PM

Post #1 of 7 (4179 views)
flip flop operator with assignment operator Can't Post

Hello,
I have following code


Code
#!/usr/bin/perl 
use warnings;
my $a;
while (<>){
if (($a=1)..4){
print $_;
}
}


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.

thanks!


wickedxter
User

Sep 26, 2014, 1:47 PM

Post #2 of 7 (4164 views)
Re: [iThunder] flip flop operator with assignment operator [In reply to] Can't Post

from the perlop site http://perldoc.perl.org/perlop.html#Range-Operators

Quote
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.



Laurent_R
Veteran / Moderator

Sep 28, 2014, 2:32 AM

Post #3 of 7 (3985 views)
Re: [iThunder] flip flop operator with assignment operator [In reply to] Can't Post

What is the purpose of your $a variable that you are not using anywhere? Try to remove it.


BillKSmith
Veteran

Sep 29, 2014, 8:46 PM

Post #4 of 7 (3679 views)
Re: [iThunder] flip flop operator with assignment operator [In reply to] Can't Post

Very strange! I have no idea why it makes a difference, but I get the expected result if I replace the left hand argument with a logical expression which always returns "true".

Code
#!/usr/bin/perl  
use warnings;
my $a;
while (<DATA>){
if (1==1 .. 4){
print $_;
}
}
__DATA__
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o


Result:

Code
a 
b
c
d

Good Luck,
Bill


Laurent_R
Veteran / Moderator

Oct 1, 2014, 10:41 AM

Post #5 of 7 (3508 views)
Re: [BillKSmith] flip flop operator with assignment operator [In reply to] Can't Post

Hi Bill,

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.


BillKSmith
Veteran

Oct 1, 2014, 12:17 PM

Post #6 of 7 (3503 views)
Re: [Laurent_R] flip flop operator with assignment operator [In reply to] Can't Post

Laurent,

I agree. The result of my "corrected" code is what we should expect.

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?


Code
#!/usr/bin/perl  
use warnings;
my $a;
while (<DATA>){
if (($a=1)..4){
print $_;
}
}
__DATA__
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o

OUTPUT

Code
a 
b
c
d
e
f
g
h
i
j
k
l
m
n
o

Good Luck,
Bill


Laurent_R
Veteran / Moderator

Oct 1, 2014, 2:37 PM

Post #7 of 7 (3498 views)
Re: [BillKSmith] flip flop operator with assignment operator [In reply to] Can't Post

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) :

Code
#!/usr/bin/perl   
use warnings;
use strict;

my $c;
while (<DATA>){
if ($c=1..4){
print $_;
}
}
__DATA__
a
b
c
d
e
f
g
...


And this way, it works fine:

Code
$ perl  flip_flop.pl 
a
b
c
d


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.


(This post was edited by Laurent_R on Oct 1, 2014, 2:42 PM)

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives