each{|i| ... }って言われても

なんだこれ?

長年同じ言語をやってると、他の言語の文法に軽くカルチャーショック。

Rubyでのイテレータ処理で

["dog","cat"].each{|s|
  p s + " is animal"
}

と書くと

"dog is animal"
"cat is animal"

と表示される。

これと同じ

何がおきてるかはわかるけど、何でそうなるかは理解できないと思い、調べてたところ

proc = Proc.new {|s|
  p s + " is animal"
}
["dog","cat"].each (&proc)

上と同じことらしい。

なんてことはない、eachメソッドの引数としてブロック付きメソッド()を渡してるだけということに。

ってことは

これでも動くのか?

["dog","cat"].each({|s|
  p s + " is animal"
})

と思ったら、これはだめらしい。

でも

["dog","cat"].each(&Proc.new{|s|
  p s + " is animal"
})

こっちは動いた。(インライン化してるだけだからそりゃそうだ…

ようするに

eachメソッドだけ特殊に見えるけど、メソッドの引数としてブロック付きメソッドを渡してるだけなので、普通のメソッドと変わらないってことだ。

ちなみに

method(val)
valは通常の引数
method(*list)
listは配列引数
method(&block)
blockはブロック引数

だそうな

雰囲気的には

JavaのActionListenerの実装なんかに似ているかも。
匿名インナークラスみたいな。

最後に

書き終わった後に思い出したけど、コーディング規則的にはブロックは{}よりdo..endが正しいらしい。

["dog","cat"].each do |s|
  p s + " is animal"
end