投稿

8月, 2012の投稿を表示しています

Rubyのyieldがようやくわかった

不勉強ゆえに「なんだかよく分からない」状態が長く続いていたが、ようやく「とりあえず使える」程度には理解できた。
class Demo   def initialize     @arr = (0..9).to_a   end   def eachLambda fn     @arr.each do |i|       fn.call(i)     end   end   def eachYield(*arg,&block)     @arr.each do |i|       yield i,*arg       #block.call(i,*arg)     end   end end Demo.new.eachLambda lambda {|i|   puts i*i } Demo.new.eachYield do |i,n|   puts i*i end Demo.new.eachYield(2) do |i,n|   puts i**n end 最近"hoge.each {|i| Foo.new(i) {|i| ... } }"のようなコードを頻繁に書いていて、だんだんコピペが億劫になってきていた。外側のブロック部分は変わらず、中身の"..."の部分だけが違うだけだというのに、すべてを記述しなければならなかった・・・自分の理解不足ゆえに。

ちょっと工夫してみようということで、すぐに思いついたのは「"..."部分をlambdaで渡そう」ということだった。そうして出来たのが、上の例にある"eachLambda"だ。呼び出し時のlambdaが浮いてる感じがする点や、いかにもブロックでありそうなところを"{}"で書かなければならない点を除けば、概ね満足できるものだった。

しかし、これを人に使ってもらう段階になって「やっぱりブロックで渡したいよね」ということになり、「yield、何やってるかよく分からない」状態から再入門することになった。

そうしてようやく、上の例にあるeachYieldのようなものが書けるようになった。もうyieldはこわくない。"block.call()"の方が分かりやすい気がするけど、もう気にしない。…