5

I have the following code

  # 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

it's not that important what's doing, although it should pretty obvious. The point is that Rubocop gives me a warning

Never use 'do' with multi-line 'while

Why should I not do that? How should I do it then?

4

2 回答 2

17

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,它仍然可以按照你的要求工作,不会抛出任何错误,而只是一个警告。但是,如果您尝试将 a Procor对象传递给它,并像我们通常所做的那样,使用关键字Method动态尝试将其转换为块,则可能会很危险。&这意味着

# 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 风格指南还建议不要使用while/until condition do while/until

我认为原因正如中田信义邮件列表中所说的那样

loop是一种kernel采用block的方法。一个引入了新的局部变量范围

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

while没有。

  while 1
    a = 1
    break   
  end
  p a #=> 1
于 2014-01-22T17:51:39.303 回答
4

Ruby 实际上有一个快捷方式while true语句loop

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
于 2014-01-22T18:03:58.843 回答