ブロックは、イテレータを実装するためによく使われています。
たとえば、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)を分けて書くことができます。
それに対してブロックを使わなかった場合は、イテレータと処理が一緒になっています。
このサンプルは簡単なのであれですが、もっと複雑な繰り返しや処理を行う場合は、このブロックの便利さがわかってくるように思います。