【问题标题】:Rubocop rule: Never use 'do' with multi-line 'whileRubocop 规则:永远不要将 'do' 与多行 'while 一起使用
【发布时间】:2014-01-22 17:45:29
【问题描述】:

我有以下代码

  # colours a random cell with a correct colour
  def colour_random!
    while true do
      col, row = rand(columns), rand(rows)
      cell = self[row,col]
      if cell.empty? then
        cell.should_be_filled? ? cell.colour!(1) : cell.colour!(0)
        break
      end
    end
  end

做什么并不重要,尽管它应该很明显。关键是 Rubocop 给了我一个警告

切勿将 'do' 与多行 'while 一起使用

为什么我不应该这样做?那我该怎么做呢?

【问题讨论】:

    标签: ruby while-loop rubocop


    【解决方案1】:

    while 是一个关键字,所以你不需要传递一个块。没有do..end 它将正常工作。下面的就好了

      def colour_random!
        while true
          col, row = rand(columns), rand(rows)
          cell = self[row,col]
          if cell.empty? then
            cell.should_be_filled? ? cell.colour!(1) : cell.colour!(0)
            break
          end
        end
      end
    

    while 是一个关键字,如果你向它传递一个块,比如do..end,它仍然可以按照你的要求工作,不会抛出任何错误,而只是一个警告。但是,如果您尝试将 ProcMethod 对象传递给它,并使用 & 关键字动态尝试将其转换为 block 可能会很危险,就像我们通常做的那样。这意味着

    # below code will work as expected just throwing an warning.
    x = 2
    while x < 2 do
      #code
    end
    

    但是如果你尝试像下面这样错误地做

    while &block # booom!! error
    

    原因是while 是一个关键字,它不支持任何to_proc 方法来满足您的需要。所以这可能很危险

    Ruby 风格指南还建议Never use while/until condition do for multi-line while/until

    我认为原因正如Nobuyoshi Nakadamailing list中所说的那样

    loop 是一个kernel 方法,它接受一个block引入了新的局部变量范围

      loop do
        a = 1
        break   
      end   
      p a #=> causes NameError
    

    while 没有。

      while 1
        a = 1
        break   
      end
      p a #=> 1
    

    【讨论】:

    • 感谢您的解释。
    • 1.这真的是块吗?我不能这样做:i=0; pr1={i+=1}; while(i&lt;10) &amp;pr1。 2. 千万不要在多行的时候使用'do',而这听起来很危险。那么......为什么它会很危险?
    • @DarekNędza 1. 这真的是块吗?是的,它确实是块 - do..end。 2. 你说的,是的,你可以这样做,这就是所谓的 single line.while can also appear in modifier position, either in a single-line statement or in a multi-line statement using a begin/end block. 3. 永远不要在 multi-line ' 中使用 'do',因为这听起来很危险.那么......为什么它会很危险? - 我没有这个答案,如果你有请分享。
    • 这么多编辑在我的屏幕上闪烁!好吧,我刚刚问过“while do end 是否被阻止。我没有想过在这种情况下它会有多大的危险。不过你的答案很好!所以“+1”。
    • "Ruby 风格指南也建议" ...是的,我后来发现 Rubocop 实际上遵循了这个规则。所以它更像是“Ruby 风格指南建议”和“Rubocop 也建议”。
    【解决方案2】:

    Ruby 实际上有一个while true 的快捷方式:the loop statement

    def colour_random!
      loop do
        col, row = rand(columns), rand(rows)
        cell = self[row,col]
        if cell.empty? then
          cell.should_be_filled? ? cell.colour!(1) : cell.colour!(0)
          break
        end
      end
    end
    

    【讨论】:

    • loop do 可用时,我不知道为什么有人会使用while true。也许它来自多年的 C/C++ 编码。
    • @CarySwoveland 我想是的。 loop 语句在各种不同的编程语言中相当少见,但是 while true 没有功能缺陷。这只是一个美丽的问题;-)
    • @CarySwoveland Loop vs while - 你可以阅读它。我的选择永远是while,而不是loop
    • @CarySwoveland 查看我的个人资料会告诉你我的背景是 C# ;)
    • 好点,@Arup,但不是在很多情况下它没有区别,在某些情况下你想要一个块,以防止其局部变量被窥探?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多