Is there a "do ... while" loop in Ruby? Is there a "do ... while" loop in Ruby? ruby ruby

Is there a "do ... while" loop in Ruby?


CAUTION:

The begin <code> end while <condition> is rejected by Ruby's author Matz. Instead he suggests using Kernel#loop, e.g.

loop do   # some code here  break if <condition>end 

Here's an email exchange in 23 Nov 2005 where Matz states:

|> Don't use it please.  I'm regretting this feature, and I'd like to|> remove it in the future if it's possible.||I'm surprised.  What do you regret about it?Because it's hard for users to tell  begin <code> end while <cond>works differently from  <code> while <cond>

RosettaCode wiki has a similar story:

During November 2005, Yukihiro Matsumoto, the creator of Ruby, regretted this loop feature and suggested using Kernel#loop.


I found the following snippet while reading the source for Tempfile#initialize in the Ruby core library:

begin  tmpname = File.join(tmpdir, make_tmpname(basename, n))  lock = tmpname + '.lock'  n += 1end while @@cleanlist.include?(tmpname) or  File.exist?(lock) or File.exist?(tmpname)

At first glance, I assumed the while modifier would be evaluated before the contents of begin...end, but that is not the case. Observe:

>> begin?>   puts "do {} while ()" >> end while falsedo {} while ()=> nil

As you would expect, the loop will continue to execute while the modifier is true.

>> n = 3=> 3>> begin?>   puts n>>   n -= 1>> end while n > 0321=> nil

While I would be happy to never see this idiom again, begin...end is quite powerful. The following is a common idiom to memoize a one-liner method with no params:

def expensive  @expensive ||= 2 + 2end

Here is an ugly, but quick way to memoize something more complex:

def expensive  @expensive ||=    begin      n = 99      buf = ""       begin        buf << "#{n} bottles of beer on the wall\n"         # ...        n -= 1      end while n > 0      buf << "no more bottles of beer"     endend

Originally written by Jeremy Voorhis. The content has been copied here because it seems to have been taken down from the originating site. Copies can also be found in the Web Archive and at Ruby Buzz Forum. -Bill the Lizard


Like this:

people = []begin  info = gets.chomp  people += [Person.new(info)] if not info.empty?end while not info.empty?

Reference: Ruby's Hidden do {} while () Loop