FlipFlop Voodoo

D

Daniel Nugent

So I was reading through the retrospective on RedHanded today and saw
the piece of flipflops
(http://redhanded.hobix.com/inspect/hopscotchingArraysWithFlipFlops.html).

Reading it I realized that I didn't quite understand how the
flipfloperator worked exactly. So I grabbed the Pickaxe2 and read
that it returns true when the state machine is in the set state at the
end of the call.

Looking at both why's examples, the ones in Pickaxe2, and through a
little experimentation of my own and once again reviewing the state
transition diagram in Pickaxe2, I figured there must be a typo.

See example 1 on pg 342:

a =3D (11..20).collect {|i| (i%4 =3D=3D 0)..(i%3 =3D=3D 0) ? i ? nil}
a -> [nil, 12, nil, nil, nil, 16, 17, 18, nil, 20]

If there isn't a typo and I'm reading it right, then 18 should not be
in the output array since the second part of the flipflop should have
triggered the state machine to go back to the unset state. Now,
Pickaxe2 mentions that when the second condition evaluates to true on
the same call as the first condition, it will still output true
anyhow.

However, it does not explain why this happens or why it also outputs
18 even though 18%3=3D=3D0 should evaluate to true and push the state
machine into the unset state.

If I'm missing something vital about this, I'd really appreciate
someone taking the time to explain it more thoroughly Because I
*think* I understand what's going on here, but my reading of Pickaxe2
would seem to indicate that I don't.
--=20
-Dan Nugent
 
E

Esteban Manchado Velázquez

So I was reading through the retrospective on RedHanded today and saw
the piece of flipflops
(http://redhanded.hobix.com/inspect/hopscotchingArraysWithFlipFlops.htm= l).
=20
Reading it I realized that I didn't quite understand how the
flipfloperator worked exactly. So I grabbed the Pickaxe2 and read
that it returns true when the state machine is in the set state at the
end of the call.
=20
Looking at both why's examples, the ones in Pickaxe2, and through a
little experimentation of my own and once again reviewing the state
transition diagram in Pickaxe2, I figured there must be a typo.
=20
See example 1 on pg 342:
=20
a =3D (11..20).collect {|i| (i%4 =3D=3D 0)..(i%3 =3D=3D 0) ? i ? nil}
^
Typo here ------------------------------------------'

Should be ":", of course. It's unrelated to what you're asking, anyway=
;-)
a -> [nil, 12, nil, nil, nil, 16, 17, 18, nil, 20]
[...]
However, it does not explain why this happens or why it also outputs
18 even though 18%3=3D=3D0 should evaluate to true and push the state
machine into the unset state.

The "problem" here is that two dot ranges _include_ the ending. What I
don't quite understand is this :)

--------------------------------- 8< ---------------------------------
zoso@velutha:~/tmp$ cat >number_list
one
two
three
four
five
zoso@velutha:~/tmp$ irb
irb(main):001:0> File.foreach('number_list') do |line|
irb(main):002:1* if line =3D~ /two/ .. line =3D~ /four/
irb(main):003:2> puts "#{line.chomp} is included in the two..four r=
ange"
irb(main):004:2> end
irb(main):005:1> if line =3D~ /two/ ... line =3D~ /four/
irb(main):006:2> puts "#{line.chomp} is included in the two...four
range"
irb(main):007:2> end
irb(main):008:1> end
two is included in the two..four range
two is included in the two...four range
three is included in the two..four range
three is included in the two...four range
four is included in the two..four range
four is included in the two...four range
=3D> nil
irb(main):009:0> (1..20).to_a
=3D> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, =
20]
irb(main):010:0> (1...20).to_a
=3D> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
--------------------------------- >8 ---------------------------------

It seems that ranges in conditions always behave as "..", even if you use=
the
"..." operator. Another, simpler, example:

--------------------------------- 8< ---------------------------------
irb(main):007:0> (1..20).each do |i|
irb(main):008:1* puts i if (i =3D=3D 4 .. i =3D=3D 5)
irb(main):009:1> end
4
5
=3D> 1..20
irb(main):010:0> (1..20).each do |i|
irb(main):011:1* puts i if (i =3D=3D 4 ... i =3D=3D 5)
irb(main):012:1> end
4
5
=3D> 1..20
--------------------------------- >8 ---------------------------------

Is there any reason for this? Is it a bug?

--=20
Esteban Manchado Vel=E1zquez <[email protected]> - http://www.foton.es
EuropeSwPatentFree - http://EuropeSwPatentFree.hispalinux.es
 
D

Daniel Nugent

I think you're wrong here in that you've misunderstood what the
purpose of the conditional range operator is.

For one, there's no typo in my original message (I'm copying right out
of Pickaxe2)

Here's the first example they give:

a =3D (11..20).collect {|i| (i%4 =3D=3D0)..(i%3 =3D=3D 0) ? i : nil)
a -> [nil, 12, nil, nil, nil, 16, 17, 18, nil, 20]

Here, when i =3D 12, we can see that the first expression evaluates to
true and the second expression evaluates to true. If the state
machine moves each time one part of the expression evaluated to true,
then it wouldn't print 12 since it would be back in the unset state
(where it was before the first expression evaluated to true). The
Pickaxe mentions this, that if they both evaluate on the same call it
will finish in the unset state but the flipflop operator would still
return true in that condition. However, when i =3D 16, it stays in the
set state until i =3D 18, when the state machine should go back to the
unset state and *not* return true if the Pickaxe is to be believed.

a =3D (11..20).collect {|i| (i%4 =3D=3D0)...(i%3 =3D=3D 0) ? i : nil)
a -> [nil, 12, 13, 14, 15, 16, 17, 18, nil, 20]

Here, when i =3D 12, the first expression evaluates to true, *but the
second expression doesn't get a chance to*. Pickaxe2 states that the
semantics of conditional ... causes a short circuit when the first
expression evaluates to true. Thus, i%3 does not evaluate to 0 until
i =3D 15. Once again, were the pickaxe to be believed, this should move
the state machine into the unset state and the flipflop operator
should not return true.

If conditional ... worked as you expected, then 12-15 should be nil in
the above example since ... would exclude 12 since it's the end of the
range (1...1.to_a =3D=3D [] for example)

So, basically, I think I understand the semantics of it, just that
there's a small error in Pickaxe2's explanation. It should say
something like if expression2 is evaluated to true, the state machine
is moved to the unset state after the operator has decided to return
true.

So I was reading through the retrospective on RedHanded today and saw
the piece of flipflops
(http://redhanded.hobix.com/inspect/hopscotchingArraysWithFlipFlops.htm= l).

Reading it I realized that I didn't quite understand how the
flipfloperator worked exactly. So I grabbed the Pickaxe2 and read
that it returns true when the state machine is in the set state at the
end of the call.

Looking at both why's examples, the ones in Pickaxe2, and through a
little experimentation of my own and once again reviewing the state
transition diagram in Pickaxe2, I figured there must be a typo.

See example 1 on pg 342:

a =3D (11..20).collect {|i| (i%4 =3D=3D 0)..(i%3 =3D=3D 0) ? i ? nil}
^
Typo here ------------------------------------------'
=20
Should be ":", of course. It's unrelated to what you're asking, anyway= ;-)
=20
a -> [nil, 12, nil, nil, nil, 16, 17, 18, nil, 20]
[...]
However, it does not explain why this happens or why it also outputs
18 even though 18%3=3D=3D0 should evaluate to true and push the state
machine into the unset state.
=20
The "problem" here is that two dot ranges _include_ the ending. What I
don't quite understand is this :)
=20
--------------------------------- 8< ---------------------------------
zoso@velutha:~/tmp$ cat >number_list
one
two
three
four
five
zoso@velutha:~/tmp$ irb
irb(main):001:0> File.foreach('number_list') do |line|
irb(main):002:1* if line =3D~ /two/ .. line =3D~ /four/
irb(main):003:2> puts "#{line.chomp} is included in the two..four r= ange"
irb(main):004:2> end
irb(main):005:1> if line =3D~ /two/ ... line =3D~ /four/
irb(main):006:2> puts "#{line.chomp} is included in the two...four
range"
irb(main):007:2> end
irb(main):008:1> end
two is included in the two..four range
two is included in the two...four range
three is included in the two..four range
three is included in the two...four range
four is included in the two..four range
four is included in the two...four range
=3D> nil
irb(main):009:0> (1..20).to_a
=3D> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, = 20]
irb(main):010:0> (1...20).to_a
=3D> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
--------------------------------- >8 ---------------------------------
=20
It seems that ranges in conditions always behave as "..", even if you use= the
"..." operator. Another, simpler, example:
=20
--------------------------------- 8< ---------------------------------
irb(main):007:0> (1..20).each do |i|
irb(main):008:1* puts i if (i =3D=3D 4 .. i =3D=3D 5)
irb(main):009:1> end
4
5
=3D> 1..20
irb(main):010:0> (1..20).each do |i|
irb(main):011:1* puts i if (i =3D=3D 4 ... i =3D=3D 5)
irb(main):012:1> end
4
5
=3D> 1..20
--------------------------------- >8 ---------------------------------
=20
Is there any reason for this? Is it a bug?
=20
--
Esteban Manchado Vel=E1zquez <[email protected]> - http://www.foton.es
EuropeSwPatentFree - http://EuropeSwPatentFree.hispalinux.es
=20
=20


--=20
-Dan Nugent
 
M

Michael Campbell

For one, there's no typo in my original message (I'm copying right out
of Pickaxe2)

Not to be a pedant, but yes, there was. Here's your original:
a =3D (11..20).collect {|i| (i%4 =3D=3D 0)..(i%3 =3D=3D 0) ? i ? nil}

The second "?" should be ":".
 
D

Daniel Nugent

Whoops, you're right about that Michael, the carat being near the
second modulo operator confused me, didn't see the second question
mark at all.

Sorry. I maintain my points otherwise.

=20
So, you've got something against pedants? ;)
=20
=20
Hal
=20
=20
=20
=20
=20


--=20
-Dan Nugent
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top