作者: rubikitch
日時: 2009/5/17(01:11)
From: kikwai@... (機械伯爵)
Subject: [TSruby:331] Re: inject メソッド
Date: Sat, 16 May 2009 22:31:23 +0900 (JST)

>> | p (1..5).inject(&:+)
>> | # =| 15
>> |
>> | p (1..5).inject(:+)
>> | # =| 15
>> |
>> | 後者の様に Symbol を渡せるのは、引数が Symbol の場合、inject が内部で
>> to_proc してるからです。
>> | Enumerable#map などでは使えません。
>> 
>> :*をわたしても自動的に &:* と同じになるように変換されるからです。
> 
>  ええ、ここは読みました(ここを読んでも、るびきちさんの説明を戴いても、
> やっぱなかなか頭がついていけないのですが)

配列の要素の合計を求めるのにいちいち .inject{|s,x| s+x} と書くのが面倒だから
.inject(:+) と書けると考えていいと思います。
sum メソッドが標準であるわけではないので。

# おそらく合計がinjectの最も典型的な例なので

>  ただ、その後の例でしつこく&を付けてる(って言い方は失礼か)ので、
> 「なんか意味あるのかしらん?」と気になったわけです。

&つきの引数は「ブロック引数」で、ブロックをオブジェクトとして渡しています。

mapメソッドの通常の使い方はこう。
[1,2,3].map{|x| x*2 }           # => [2, 4, 6]

ブロック引数を使うと…
def map_test(&block)
  [1,2,3].map(&block)
end
map_test {|x| x*2 }             # => [2, 4, 6]

map_testのブロックが &block という仮引数に Proc オブジェクトで渡って、
それをそのまま map メソッドに丸投げしています。

ProcじゃなくてSymbolを渡したときは、前述のように Symbol#to_proc によってProcに変換されます。
省略記法みたいなものですか。

>> func \&foo
>> 
>> とやるようなものです。
> 
>  ……かえってわかんないです(号泣)
> 
>  うわぁ、ラクダ本ラクダほん〜〜〜っ!
> 
>  ……
> 
>  &はサブルーチンだけど、\ってなんだっけ?

リファレンスですね。ポインタ。

--
rubikitch
Blog: http://d.hatena.ne.jp/rubikitch/
Site: http://www.rubyist.net/~rubikitch/