Ruby中是否有" do ... while"循环?

时间:2020-03-06 14:45:23  来源:igfitidea点击:

我正在使用此代码让用户输入名称,而程序将它们存储在数组中,直到他们输入一个空字符串(他们必须在每个名称后按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中似乎不存在这种类型的循环。有人可以建议一种更好的方法吗?

解决方案

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 += 1
end 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 false
do {} 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 > 0
3
2
1
=> 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 + 2
end

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

最初由Jeremy Voorhis撰写。内容已被复制到此处,因为它似乎已从原始站点中删除。副本也可以在Web存档和Ruby Buzz论坛中找到。 -蜥蜴比尔

像这样:

people = []

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

参考:Ruby的Hidden do {} while()循环

这个怎么样?

people = []

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

ppl = []
while (input=gets.chomp)
 if !input.empty?
  ppl << input
 else
 p ppl; puts "Goodbye"; break
 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 ... end的内容之前进行评估,但事实并非如此。观察:

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

虽然我很高兴再也没有看到这个成语,但是begin ... 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

a = 1
while true
  puts a
  a += 1
  break if a > 10
end