首页 文章

Ruby中有“do ... while”循环吗?

提问于
浏览
420

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

10 回答

  • -3

    这个怎么样?

    people = []
    
    until (info = gets.chomp).empty?
      people += [Person.new(info)]
    end
    
  • 11
    ppl = []
    while (input=gets.chomp)
     if !input.empty?
      ppl << input
     else
     p ppl; puts "Goodbye"; break
     end
    end
    
  • 2

    这是另一个:

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

    这现在正常工作:

    begin
        # statment
    end until <condition>
    

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

    Matz建议这样做:

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

    CAUTION

    begin <code> end while <condition> 被Ruby的作者Matz拒绝 . 相反,他建议使用 Kernel#loop ,例如

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

    有关详细信息,请参阅:http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/6745or via Wayback),以及此wiki:http://rosettacode.org/wiki/Loops/Do-while#Ruby

  • 100

    我在Ruby核心库中读取Tempfile #initumize的源代码时发现了以下片段:begin
    tmpname = File.join(tmpdir,make_tmpname(basename,n))
    lock = tmpname'.lock'
    n = 1
    结束时@@ cleanlist.include?(tmpname)或
    File.exist?(lock)或File.exist?(tmpname)
    乍一看,我假设while修饰符将在begin ... end的内容之前进行评估,但事实并非如此 . 观察:>>开始
    ?>把“do {} while()”

    结束而错误
    做{} while()
    =>无
    正如您所料,循环将在修饰符为true时继续执行 . >> n = 3
    => 3
    开始
    ?>把n
    n - = 1
    结束时n> 0
    3
    2
    1
    =>无
    虽然我很高兴再也看不到这个成语,但开始......结束是非常强大的 . 以下是一个常见的成语,用于记忆没有参数的单线方法:def昂贵
    @expensive || = 2 2
    结束
    这是一个丑陋但快速的方式来记忆更复杂的东西:def昂贵
    @expensive || =
    开始
    n = 99
    buf =“”
    开始
    buf <<“#
    瓶壁上的啤酒\ n”
    #...
    n - = 1
    当n> 0时结束
    buf <<“没有更多的啤酒瓶”
    结束
    结束

    最初由Jeremy Voorhis撰写 . 这里的内容已被复制,因为它似乎已从原始网站上删除 . 副本也可以在Web ArchiveRuby Buzz Forum中找到 . - 蜥蜴

  • 588

    像这样:

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

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

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

    这是来自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
    
  • 3

    从我收集到的,Matz不喜欢这个结构

    begin
        <multiple_lines_of_code>
    end while <cond>
    

    因为,它的语义不同于

    <single_line_of_code> while <cond>
    

    因为第一个构造在检查条件之前首先执行代码,第二个构造在执行代码之前首先测试条件(如果有的话) . 我认为Matz更喜欢保留第二个结构,因为它匹配if语句的一个行结构 .

    即使是if语句,我也从不喜欢第二种结构 . 在所有其他情况下,计算机从上到下执行从左到右(例如||和&&)的代码 . 人类从上到下从左到右阅读代码 .

    我建议使用以下结构:

    if <cond> then <one_line_code>      # matches case-when-then statement
    
    while <cond> then <one_line_code>
    
    <one_line_code> while <cond>
    
    begin <multiple_line_code> end while <cond> # or something similar but left-to-right
    

    我不知道这些建议是否会用其他语言进行解析 . 但在任何情况下,我都倾向于保持从左到右的执行以及语言的一致性 .

相关问题