Правило 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