ブロックの作り方(再)

ブロックは、イテレータを実装するためによく使われています。
たとえば、Arrayクラスのeachメソッドでは、

list = ["hoge", "fuga", "piyo"]
list.each{ |element| puts element}

といった具合にブロックを使って繰り返し処理を行えます。

このようなブロックを取れるメソッドは、メソッド内でyield文を使っています。
たとえば、与えた数を2倍づつして返すメソッドは

def two_times_to_max(num, max=100)
  while true
    num *= 2
    break if num > max
    yield num
  end
end

two_times_to_max(3){|num| puts num}

出力結果:
6
12
24
48
96

のように書けます。
yieldが実行されるたびに、ブロックに制御が戻ります。


これをブロックを使わずに書くと

max = 100
num = 3
while true
  num *= 2
  break if num > max
  puts num
end

のようになります。


一見どちらでも変わらないように感じますが、ブロックで書いた場合は、イテレータの箇所と処理の内容(この例ではputs num)を分けて書くことができます。
それに対してブロックを使わなかった場合は、イテレータと処理が一緒になっています。


このサンプルは簡単なのであれですが、もっと複雑な繰り返しや処理を行う場合は、このブロックの便利さがわかってくるように思います。