Ruby block/proc/lambda/yeild

yield?

  • ブロックを呼び出すもの
  • 内部にyieldを持っている以上「ブロックを引数として受けとるメソッドである」ということを認識しないといけない。

Proc

  • ブロックをオブジェクト化したもの
  • Procオブジェクトはcallで呼び出すことが出来る
  • Procに引数を期待する書き方も出来る
  • Proc.newとlambdaはほぼ同義

ブロックとは引数で渡す

#メソッド定義
def give_me_block( &block )
  block.call
end

#実行
give_me_block do
  p "Hello, block!"
end
=> "Hello, block!"

上の例を yieldをつかったら

#メソッド定義
#def give_me_block( &block )
#  block.call
#end

#メソッド定義
def give_me_block    # (&block)を除去
  yield
end

注意

  • block引数は一番最後に定義
    • 以下はNG
    • def give_me_block( &block1, param1 )
    • def give_me_block( &block1, &block2 )

&blockの「&」って?

&を付けることで、実際に引数にブロックが渡ってきた際、 Procオブジェクトに変換している。

Procオブジェクトって?

  • ブロックをオブジェクト化したものがProc
    • ブロックがそれ単体では存在できないことを思い出す (→オブジェクト化してしまえばok)
    • ブロックをオブジェクトに変換することで、引き渡されたメソッド(give_me_block)内で扱えるようにする
  • Procオブジェクトは、callで呼び出すことが出来る
    • 上のblockを引数で渡す例で、2行目のblock.callの正体はこれ。

Procとlambdaの違い

두번째 다른 점은 lambda는 diminutive return을 할 수 있다는 점이다. 예컨데, Proc는 값을 반환하면 메서드를 중단한다. 따라서 메서드의 최종 반환 값은 Proc의 반환값이 된다. 하지만 lambda는 반환 후에도 메서드가 계속 된다. 다음 예를 보자.

References

results matching ""

    No results matching ""