Idiom wanted: do-while

A

Adam Shelly

So I was working on the quiz solution, and
I had some code like this:

b =3D simulate board,m
while another_turn?(b,m)
b =3D simulate b,m
end


If I was doing this in C, I'd use a do-while loop instead, to avoid
repeating the line outside the loop:

b =3D board;
do {
b =3D simulate(b.m);
}
while ( another_turnta(b,m));

What's the do-while idiom in ruby?
I ended up with this, but it needs an extra flag variable:

b,taketurn =3D board,true
while taketurn
b =3D simulate b,m
taketurn =3D another_turn?(b,m)
end

Is there a ruby idiom for do-while?

-Adam
 
J

James Edward Gray II

So I was working on the quiz solution, and
I had some code like this:

b = simulate board,m
while another_turn?(b,m)
b = simulate b,m
end


If I was doing this in C, I'd use a do-while loop instead, to avoid
repeating the line outside the loop:

b = board;
do {
b = simulate(b.m);
}
while ( another_turnta(b,m));

What's the do-while idiom in ruby?
I ended up with this, but it needs an extra flag variable:

b,taketurn = board,true
while taketurn
b = simulate b,m
taketurn = another_turn?(b,m)
end

Is there a ruby idiom for do-while?

I favor:

loop do
# ... some action ...
break unless ...
end

Hope that helps.

James Edward Gray II
 
G

gabriele renzi

Adam Shelly ha scritto:
So I was working on the quiz solution, and
I had some code like this:

b = simulate board,m
while another_turn?(b,m)
b = simulate b,m
end


If I was doing this in C, I'd use a do-while loop instead, to avoid
repeating the line outside the loop:

b = board;
do {
b = simulate(b.m);
}
while ( another_turnta(b,m));

What's the do-while idiom in ruby?

you could do

begin
...
end while somecondition

but I seem to recall it is somewhat "deprecated" and you should follow
James' suggestion
 
A

Andy Delcambre

You can also do
irb(main):011:0> begin
irb(main):012:1* puts "Once"
irb(main):013:1> end while nil
Once
=3D> nil

Which is what I usually do.

- Andy Delcambre
 
A

ara.t.howard

So I was working on the quiz solution, and
I had some code like this:

b = simulate board,m
while another_turn?(b,m)
b = simulate b,m
end


If I was doing this in C, I'd use a do-while loop instead, to avoid
repeating the line outside the loop:

b = board;
do {
b = simulate(b.m);
}
while ( another_turnta(b,m));

What's the do-while idiom in ruby?
I ended up with this, but it needs an extra flag variable:

b,taketurn = board,true
while taketurn
b = simulate b,m
taketurn = another_turn?(b,m)
end

Is there a ruby idiom for do-while?

harp:~ > cat a.rb
i = 0

(
p i
i += 1
) while i < 3


harp:~ > ruby a.rb
0
1
2

cheers.

-a
--
===============================================================================
| ara [dot] t [dot] howard [at] noaa [dot] gov
| all happiness comes from the desire for others to be happy. all misery
| comes from the desire for oneself to be happy.
| -- bodhicaryavatara
===============================================================================
 
B

Brian Mitchell

harp:~ > cat a.rb
i =3D 0

(
p i
i +=3D 1
) while i < 3


harp:~ > ruby a.rb
0
1
2

Not quite. That is just a while loop:

( puts "foo" ) while nil
.. nil

which is as always, equivalent to:

while nil
puts "foo"
end


If you really need a do while loop it is not hard to use loop to
accomplish what you need. If you want something more complex you could
easily get this to work:

lambda do
...
end.while { ... }

All you would need is something like this:

class Proc
def while
loop do
result =3D call
return result unless yield
end
end
end

I am sure there is plenty of room for improving this example too.

Brian.
 
A

Adam Shelly

I was certain I had tried that....
But that works exactly the way I want.
Thanks,
-Adam
 
J

James Edward Gray II

I was certain I had tried that....
But that works exactly the way I want.

But hopefully you followed the Ruby Core link in this thread and saw
Matz explaining how he would like to remove it from the language so
we shouldn't be using it. Stick with loop do ... end.

James Edward Gray II
 
S

Steve Litt

I favor:

loop do
# ... some action ...
break unless ...
end

I do this quite a bit, but it's not structured programming and is a little
like a goto. Break can improve readability on small loops, but on large loops
maintained by multiple people it can become a nightmare.

SteveT

Steve Litt
http://www.troubleshooters.com
(e-mail address removed)
 
J

James Edward Gray II

I do this quite a bit, but it's not structured programming and is a
little
like a goto. Break can improve readability on small loops, but on
large loops
maintained by multiple people it can become a nightmare.

Which is probably a sign that method calls are needed. Heck, I think
two programmers working on the same loop is a sign of that. ;)

James Edward Gray II
 
M

Mark Ericson

------=_Part_7814_9887629.1134439400957
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

I did, and I was curious about the statement
Because it's hard for users to tell

begin <code> end while <cond>

works differently from

<code> while <cond>
in what ways are they different? Any code examples to show the difference?


But hopefully you followed the Ruby Core link in this thread and saw
Matz explaining how he would like to remove it from the language so
we shouldn't be using it. Stick with loop do ... end.

James Edward Gray II

------=_Part_7814_9887629.1134439400957--
 
A

Andy Delcambre

The begin end one functions like a do while loop, the body will always
get executed at least once, wherease the <code> while <cond> will
only get exectuted if the cond is true.

irb(main):001:0> begin
irb(main):002:1* p "once"
irb(main):003:1> end while nil
"once"
=3D> nil
irb(main):004:0> p "once" while nil
=3D> nil

- Andy Delcambre
 
S

Stephen Waits

Mark said:
in what ways are they different? Any code examples to show the difference?

Andy already answered, but I thought I'd take my shot at it too.

begin <code> end while <cond>

is guaranteed to execute <code> at least one time; whereas,

<code> while <cond>

may never execute <code> because it is exactly equivalent to

while <cond> <code>

in the same way that

if <cond> <code>

is equivalent to

<code> if <cond>

The whole begin/end thing is definitely unnecessary, and can (and
frequently does) become a source of confusion; it's a good thing that
it's going away. The sooner the better.

--Steve
 
J

Jacob Fugal

I do this quite a bit, but it's not structured programming and is a littl= e
like a goto.

I see no similarity. 'goto' is unstructured because the target point
is completely arbitrary; place a label in your code then jump right to
it. 'break' is completely structured; it's part of the structure of
the enclosing loop and its target is defined by that structure.
Break can improve readability on small loops, but on large loops
maintained by multiple people it can become a nightmare.

I agree with James; if the loop is long enough or complex enough for
these to be a problem, the body of the loop probably needs some
serious refactoring.

Jacob Fugal
 
S

Steve Litt

I see no similarity. 'goto' is unstructured because the target point
is completely arbitrary; place a label in your code then jump right to
it. 'break' is completely structured; it's part of the structure of
the enclosing loop and its target is defined by that structure.

Ahh -- I found a reference. See
http://en.wikipedia.org/wiki/Structured_programming, and note Dijkstra's
structured programming definition -- every block of code has one entry point
and one exit point. Break statements clearly violate the "one exit point"
rule. I was taught the Dijkstra definition at Santa Monica College.

That same page also lists a definition not demanding a single exit point,
allowing for break. I saw a lot of that when I left Santa Monica College and
programmed in the real world. I also saw code that was horribly obfuscated by
break statements. More on that...
I agree with James; if the loop is long enough or complex enough for
these to be a problem, the body of the loop probably needs some
serious refactoring.

It absolutely does. Trouble is, in many shops loops start out 8 lines of code,
and over many, many years, maintenance programmers, many not experienced,
most not being privy to original design considerations, add features demanded
by management on ultra-tight schedules. A few years later it's 100 lines of
code and the break statement is in the middle of it.

Under those circumstances, the once understandable break statement authored by
the original programmer can result in unfathomable code, especially if others
add more break statements.

What I'm saying isn't as important today as it was 15 years ago, when many
programs were not object oriented. Obviously, something like My_data.to_s can
easily be refactored just from its name. 15 years ago,
process_all_valid_incoming_paid_records() could not be.

By habit, I always think twice before using break or continue (redo in Ruby).
If I still want to use it, then I go ahead.

SteveT

Steve Litt
http://www.troubleshooters.com
(e-mail address removed)
 
J

James Edward Gray II

Ahh -- I found a reference. See
http://en.wikipedia.org/wiki/Structured_programming, and note
Dijkstra's
structured programming definition -- every block of code has one
entry point
and one exit point.

The loop do ... end construct is infinite. You must add a break to
end it. With one break, it has exactly one entry and exit point.
It absolutely does. Trouble is, in many shops loops start out 8
lines of code,
and over many, many years, maintenance programmers, many not
experienced,
most not being privy to original design considerations, add
features demanded
by management on ultra-tight schedules. A few years later it's 100
lines of
code and the break statement is in the middle of it.

You may be describing where you work, but you are certainly not
describing where I do. ;)

I've got two words for you: Unit tests. They were invented to
address every single issue you just listed (plus some!) and I assure
you, they work. You really, really should give them a try. It will
be the best gift you ever give yourself, I promise.

James Edward Gray II
 
J

Jamis Buck

Ok, I admit I'm coming onto this thread a bit late in the game, so
someone else might have already suggested this:

i = 0
begin
puts i
i += 1
end until i > 10

- Jamis
 
C

Chad Perrin

I've got two words for you: Unit tests. They were invented to
address every single issue you just listed (plus some!) and I assure
you, they work. You really, really should give them a try. It will
be the best gift you ever give yourself, I promise.

It's certainly good policy to use unit tests. On the other hand, coding
in a manner that is in any way less easy to maintain because you know
that the way you write code will ensure that the problem is taken care
of doesn't address the issue of what happens if someone else, with less
ingrained good habits, comes along and takes over.

Um. I'm not entirely certain that was coherent.
 
J

James Edward Gray II

On the other hand, coding
in a manner that is in any way less easy to maintain because you know
that the way you write code will ensure that the problem is taken care
of doesn't address the issue of what happens if someone else, with
less
ingrained good habits, comes along and takes over.

At the risk of sounding like a broken record, I think one of the big
advantages of Unit Tests is that they encourage you to code in a
manner that is easier to maintain (because it's also easier to test).

As for when someone else jumps in, you show them your test suit and
how it works and pray it's catching. ;) Seriously, you have to
worry about you first. The rest of the world takes time. (I did ask
in my last job interview if the company covered their software with
Unit Tests though! :D )

James Edward Gray II
 

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

Forum statistics

Threads
474,273
Messages
2,571,363
Members
48,047
Latest member
prince15

Latest Threads

Top