Ond*_*cek 5 ruby while-loop 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
Run Code Online (Sandbox Code Playgroud)
尽管它应该非常明显,但它正在做什么并不重要.关键是Rubocop给了我一个警告
切勿在多线时使用'do'
我为什么不这样做?那我该怎么办?
Aru*_*hit 16
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
Run Code Online (Sandbox Code Playgroud)
while是一个关键字,如果你传递一个块,比如do..end,它仍然可以按你的要求去做,不会抛出任何错误,而只是一个警告.但是,如果您尝试将一个Proc或Method对象传递给它,并动态尝试使用关键字将其转换为块&,这可能会很危险,正如我们通常所做的那样.这意味着
# below code will work as expected just throwing an warning.
x = 2
while x < 2 do
#code
end
Run Code Online (Sandbox Code Playgroud)
但如果你试图像下面那样错误地做
while &block # booom!! error
Run Code Online (Sandbox Code Playgroud)
原因是while关键字,它不支持任何to_proc方法来满足您的需求.所以它可能很危险.
Ruby风格指南还建议永远不要while/until condition do用于多线 while/until
我认为原因是Nobuyoshi Nakada在邮件列表中说
loop是一种kernel采取阻止的方法.阿块引入了新的局部变量范围.
loop do
a = 1
break
end
p a #=> causes NameError
Run Code Online (Sandbox Code Playgroud)
while 没有.
while 1
a = 1
break
end
p a #=> 1
Run Code Online (Sandbox Code Playgroud)