Правило Rubocop: никогда не используйте "делать" с многострочным

У меня есть следующий код

  # 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

не так важно, что происходит, хотя это должно быть довольно очевидно. Дело в том, что Рубокоп дает мне предупреждение

Никогда не используйте "делать" с многострочным

Почему я не должен этого делать? Как мне тогда это сделать?

2 ответа

Решение

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, он все еще работает так, как вы просили, не выдавая никакой ошибки, а просто предупреждение. Но это может быть опасно, если вы попытаетесь пройти Proc или же 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 метод, который занимает блок. Блок вводит новую область видимости локальной переменной.

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

while не делает.

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

Руби на самом деле имеет ярлык для 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
Другие вопросы по тегам