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()"の方が分かりやすい気がするけど、もう気にしない。

でも、よくよく見てみると、まだよく分からないものがる。"block"の前にあるアンパサンド"&"だ。この人は一体何をする人なのか、そこまではまだ勉強していない。

 http://docs.ruby-lang.org/ja/1.8.7/doc/symref.html#and
 http://docs.ruby-lang.org/ja/1.8.7/doc/symref.html#ast

コメント

このブログの人気の投稿

[Java] 母音か子音か

git-svnでFILE was not found in commit HASH

駄文