Idiom wanted: do-while

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?

-Adam

I favor:

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

Hope that helps.

James Edward Gray II

···

On Dec 12, 2005, at 4:34 PM, Adam Shelly wrote:

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?

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

···

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?

-Adam

harp:~ > cat a.rb
   i = 0

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

   harp:~ > ruby a.rb
   0
   1
   2

cheers.

-a

···

On Tue, 13 Dec 2005, Adam Shelly wrote:

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?

--

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

===============================================================================

[ruby-core:06745]

···

On Tue, Dec 13, 2005 at 07:42:59AM +0900, James Edward Gray II wrote:

>Is there a ruby idiom for do-while?

I favor:

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

--
Mauricio Fernandez

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 = call
      return result unless yield
    end
  end
end

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

Brian.

···

On 12/12/05, ara.t.howard@noaa.gov <ara.t.howard@noaa.gov> wrote:

   harp:~ > cat a.rb
   i = 0

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

   harp:~ > ruby a.rb
   0
   1
   2

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

slitt@troubleshooters.com

···

On Monday 12 December 2005 05:42 pm, James Edward Gray II wrote:

> Is there a ruby idiom for do-while?

I favor:

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

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

Which is what I usually do.

- Andy Delcambre

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. :wink:

James Edward Gray II

···

On Dec 12, 2005, at 7:36 PM, Steve Litt wrote:

On Monday 12 December 2005 05:42 pm, James Edward Gray II wrote:

Is there a ruby idiom for do-while?

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.

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

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

···

On 12/12/05, Steve Litt <slitt@earthlink.net> wrote:

On Monday 12 December 2005 05:42 pm, James Edward Gray II wrote:

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

···

On 12/12/05, Andy Delcambre <adelcambre@gmail.com> wrote:

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

Which is what I usually do.

- Andy Delcambre

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

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
Structured programming - Wikipedia, 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...

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

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

slitt@troubleshooters.com

···

On Tuesday 13 December 2005 11:09 am, Jacob Fugal wrote:

On 12/12/05, Steve Litt <slitt@earthlink.net> wrote:
> On Monday 12 December 2005 05:42 pm, James Edward Gray II wrote:

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

···

On Dec 12, 2005, at 6:19 PM, Adam Shelly wrote:

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

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.

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
Structured programming - Wikipedia, 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.

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.

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. :wink:

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

···

On Dec 13, 2005, at 7:20 PM, Steve Litt wrote:

On Tuesday 13 December 2005 11:09 am, Jacob Fugal wrote:

On 12/12/05, Steve Litt <slitt@earthlink.net> wrote:

On Monday 12 December 2005 05:42 pm, James Edward Gray II wrote:

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

···

On Dec 13, 2005, at 6:20 PM, Steve Litt wrote:

On Tuesday 13 December 2005 11:09 am, Jacob Fugal wrote:

On 12/12/05, Steve Litt <slitt@earthlink.net> wrote:

On Monday 12 December 2005 05:42 pm, James Edward Gray II wrote:

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.

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
Structured programming - Wikipedia, 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...

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.

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
slitt@troubleshooters.com

> > > 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.
>
> 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
Structured programming - Wikipedia, 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.

I'll concede that, but refer to James comment (about one break in a
loop do...end being a single exit point). However, I'd lean towards
the looser definition you mention below. Otherwise, having a function
with more than one return in it (e.g. "return false unless
precondition") would not be structured, and I'd much rather be able to
return early then have to wrap the remainder of the function body in
an if statement.

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

Just because break can be abused doesn't make it wrong.

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

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.

Hence the need for continuous refactoring. If that's not taking place,
it management's and/or the developers' fault, not the break
statement's.

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.

Again, abuse doesn't mean the item being abused is at fault.

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.

Point conceded.

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.

That's a good principle, one I wish many programmers would follow. I,
too, have been bitten by unclear breaks. But I've also been bitten by
unclear conditions in 'if' statements, 'while' statements when 'each'
with a block should have been used, etc. That doesn't mean that 'if'
statements or 'while' statements should be considered harmful. This is
the impression I got about your opinion regarding 'break' when you
lumped it with 'goto'.

Jacob Fugal

···

On 12/13/05, Steve Litt <slitt@earthlink.net> wrote:

On Tuesday 13 December 2005 11:09 am, Jacob Fugal wrote:
> On 12/12/05, Steve Litt <slitt@earthlink.net> wrote:
> > On Monday 12 December 2005 05:42 pm, James Edward Gray II wrote:

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?

···

On 12/12/05, James Edward Gray II <james@grayproductions.net> wrote:

On Dec 12, 2005, at 6:19 PM, Adam Shelly wrote:

> 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

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.

···

On Wed, Dec 14, 2005 at 10:36:50AM +0900, James Edward Gray II wrote:

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.

--
Chad Perrin [ CCD CopyWrite | http://ccd.apotheon.org ]

unix virus: If you're using a unixlike OS, please forward
this to 20 others and erase your system partition.

It's definitely not the break statement's fault. It might not be the
developer's or management's either. It might be the fault of the
marketplace, which in turn is nobody's fault -- it is what it is.

If taking the time to understand the code, in preparation for
refactoring, will cause a loss of customers, refactoring can wait
(and unfortunately usually waits until a clean rewrite).

That being said, I've always tried to refactor when possible. A lot
of times management doesn't even know -- you just rewrite
problematic parts.

By the way, how do you like often maintained, never refactored code
where they have three different variables representing essentially
the same thing, and you need to decide which one to use and which
one to set?

SteveT

Steve Litt

slitt@troubleshooters.com

···

On Wednesday 14 December 2005 11:24 am, Jacob Fugal wrote:

Hence the need for continuous refactoring. If that's not taking
place, it management's and/or the developers' fault, not the
break statement's.

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"
=> nil
irb(main):004:0> p "once" while nil
=> nil

- Andy Delcambre

···

On 12/12/05, Mark Ericson <mark.ericson@gmail.com> wrote:

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?

On 12/12/05, James Edward Gray II <james@grayproductions.net> wrote:
>
> On Dec 12, 2005, at 6:19 PM, Adam Shelly wrote:
>
> > 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
>
>