対象:
CRuby
JRuby

ブロック付きメソッド呼び出しとブロックが渡されたか否かの判定

Rubyの特徴としてメソッドにブロックを渡すことができる(ブロック付きメソッド呼び出し)が、これを自作のメソッドでも利用したい場合はどうすれば良いだろうか。該当メソッドにはブロックが必ず渡されるのであれば、自作のメソッドの中ではyieldを呼び出すだけである。

def method1(num)
  yield(num * 2) # 渡された数を2倍してブロックに渡す
end

# ブロック付きメソッド呼び出し
method1(10) do |x|
  p x
end

ただし、上記のmethod1にブロックを渡さない場合はyield called out of block (LocalJumpError)が発生してしまう。例えば、IO.openメソッド等はブロックを渡せばそれを実行してくれるが、ブロックをを渡さなければとIOオブジェクトを返す仕様となっている。

これを実現するにはメソッド内でblock_given?メソッドでブロックが渡されたかどうか判定し、ブロックが渡されなかった場合にはyieldを呼ばないようにしなければならない。あるいはblock_given?メソッドの代わりにdefined? yieldを利用することもできる。

def method1(num)
  if block_given? # ブロックが渡されたか否か
    yield(num * 2) # 渡された数を2倍してブロックに渡す
  end

  return num * 2 # 渡された数を2倍して戻り値として返す
end

# ブロック付きメソッド呼び出し
#method1(10) do |x|
#  p x
#end

# ブロックなしのメソッド呼び出し
p method1(10)

上記の改良したmethod1では、ブロックが渡された場合そのブロックに渡された数の2倍を渡し、それ以外は渡された数の2倍を戻り値として返している。これによってmethod1はブロックを渡す書き方と単に戻り値を得る書き方の2通りができるようになる。

yield
Kernel.#block_given?
(2010/07/09)

新着情報
【iOS Objective-C, Swift Tips】画像の向きを指定して保存する(Swift)
【iOS Objective-C, Swift Tips】UIImagePickerControllerの表示を日本語にする(Swift)
【iOS Objective-C, Swift Tips】ウィンドウの階層構造を3D表示する(Swift)

Copyright(C) 2004-2014 モバイル開発系(K) All rights reserved.
[Home]