5

次のコードがあります

  # 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 が警告を表示することです。

複数行の 'while' で 'do' を使用しない

なぜ私はそれをすべきではないのですか?ではどうすればいいのでしょうか?

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だけではなく、エラーをスローせずに、要求どおりに機能します。しかし、通常のようにorオブジェクトを渡して、キーワードを使用して動的にブロックに変換しようとすると、危険な場合があります。つまりProcMethod&

# 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 for multi-lineも提案されています。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
于 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 に答える