5.3 ブロック付きメソッドの定義
ブロック付きメソッドの使い方については3.2で解説した。今回はその定義の仕方について解説する。ブロック付きメソッドとは、メソッドにブロックと呼ばれる処理のまとまりを渡して、メソッド内でブロックを呼び出すことができるメソッドのことである。
初めに、ブロック付きメソッドの使い方を振り返ってみよう。
[メソッド名](メソッド引数){|ブロック引数|
処理...
}
#例
a = [1, 2, 3]
a.each(){|i|
p i
}
#=> 1\n2\n3\n
では実際にブロック付きメソッドを定義するときに渡されたブロックを呼び出すにはどうすればいいのだろうか? 以下のrunメソッドを見てみよう。
def run
yield
end
run{ p 'Hello'}
#=> "Hello"
このrunメソッドはブロック付きメソッドの定義の仕方を使って定義された、渡されたブロックをそのまま実行するメソッドである。runメソッド内のyieldメソッドは渡されたブロックを実行するメソッドである。ブロック引数を渡すにはそのままyieldに渡せばよい。
def run
yield(1, 2, 3)
end
run{|a, b, c|
puts "#{a}, #{b}, #{c}"
}
#=> 1, 2, 3
ブロック付きメソッドの良いところは、メソッド内の処理の一部を呼び出し時に渡すことで、処理の抽象度を上げられることである。例えば、配列の要素を先頭から一つひとつ取り出してブロックに渡すeachメソッドがあるが、ブロック付きメソッドを利用せずに同様の処理をしようとすると、配列の先頭から取り出す部分の処理を繰り返し書かなければならない。
for i in array1
...
end
for i in array2
...
end
ブロック付きメソッドを使えば、異なる部分のみを変えて取り出す部分の処理を再利用できる。
# ブロックのみ書き換えれば良い。
array1.each(){|i| ... }
array2.each(){|i| ... }
実際、配列を操作するためのメソッドの多くはeachメソッドのブロック部分を変えることで定義されている(chapter7.3のEnumerableを参照)。