我使用这段代码让用户输入名称,而程序将它们存储在一个数组中,直到他们输入一个空字符串(他们必须在每个名称后按enter):

people = []
info = 'a' # must fill variable with something, otherwise loop won't execute

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

这段代码在do…while循环:

people = []

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

在这段代码中,我不需要将信息分配给一些随机字符串。

不幸的是,Ruby中似乎不存在这种类型的循环。谁能提出一个更好的方法来做这件事?


当前回答

这是hubbardr的死链接到我博客的全文文章。

我在Ruby核心库中读取Tempfile#initialize的源代码时发现了以下代码片段:

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

乍一看,我以为while修饰符会在begin…结束,但事实并非如此。观察:

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

正如您所期望的那样,当修饰符为true时,循环将继续执行。

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

虽然我很高兴再也不会看到这个习语,但开始吧……End是非常强大的。下面是一个常用的习语来记住没有参数的一行方法:

def expensive
  @expensive ||= 2 + 2
end

下面是一个丑陋但快速记住更复杂事物的方法:

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" 
    end
end

其他回答

现在可以正常工作了:

begin
    # statment
end until <condition>

但是,它可能在将来被删除,因为begin语句是违反直觉的。参见:http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/6745

Matz (Ruby的创造者)建议这样做:

loop do
    # ...
    break if <condition>
end

这是另一个:

people = []
1.times do
  info = gets.chomp
  unless info.empty? 
    people += [Person.new(info)]
    redo
  end
end

这是hubbardr的死链接到我博客的全文文章。

我在Ruby核心库中读取Tempfile#initialize的源代码时发现了以下代码片段:

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

乍一看,我以为while修饰符会在begin…结束,但事实并非如此。观察:

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

正如您所期望的那样,当修饰符为true时,循环将继续执行。

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

虽然我很高兴再也不会看到这个习语,但开始吧……End是非常强大的。下面是一个常用的习语来记住没有参数的一行方法:

def expensive
  @expensive ||= 2 + 2
end

下面是一个丑陋但快速记住更复杂事物的方法:

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" 
    end
end
ppl = []
while (input=gets.chomp)
 if !input.empty?
  ppl << input
 else
 p ppl; puts "Goodbye"; break
 end
end
a = 1
while true
  puts a
  a += 1
  break if a > 10
end