ROUTE 3390

備忘録的な用途で書いていますが、どなたかの役に立つ事があれば嬉しいです。

Perlには無いRubyのyield文に少し嫉妬を覚えた

最近Rubyを勉強していて、今日yield文というのに出会った。
忘れないようにメモ

yield文はこんな感じで書く

def foo ( name )
  yield('おはよう' + name)
  yield('おやすみ' + name)
end

foo( 'sasakure' ) do | message |
  puts message
end

結果はこのように表示される

おはようsasakure
おやすみsasakure

fooというメソッドの中でyieldが実行されるたびに、
呼び出し元の後ろに書かれたdoブロックが実行される。


最初にこれ見た時は、
yieldが呼ばれる度に、doブロックを実行する処理が溜まっていって、
fooメソッドが終わった後で順番に実行されるのか、、、とか思ってたけど違った。


fooメソッドの中から、doブロックに飛び出してきて、
またfooメソッドの中に戻って、またdoブロックに飛び出してくる。


なにこれ新しい!!!(すくなくとも僕にとっては)


Perlで書くとこんな感じの動きですね

sub foo {
    my ($name, $cb, ) = @_;
    $cb->('おはよう' . $name);
    $cb->('おやすみ' . $name);
}

foo( 'sasakure', sub{ print shift . "\n"; } );

渡した無名関数がyieldした時に呼ばれるみたいな



それと!
yield文を調べる事で、初めてdoブロックについてもちゃんと理解できた。


Perlでブロックっていうと{}この範囲を指すけど、
Rubyでは do 〜 endを指す
※ただしdo endは {}に置き換えられるよ


んで、このdoブロックはperlと違って、単体では書けない。
必ずメソッドの後ろにくっついて宣言される。

そして、ブロック内が実行されるのは、その前のメソッド内でyieldが呼ばれた時になる。


配列のeacheメソッドも中でyield呼んでるって理解してもいいのかな?

list = [0,1,2,3]
list.each do | num |
  puts num
end

このyield文、覚えてしまうとなかなか便利かもしれない。
ちょっとPerlでも書きたくなるなぁ