2010/1/7 Rick DeNatale <rick.denatale / gmail.com>:
> On Thu, Jan 7, 2010 at 4:50 AM, Robert Klemme
> <shortcutter / googlemail.com> wrote:
>> On 01/07/2010 05:00 AM, Ruby Newbee wrote:

>> I don't know Python's reduce but a few things are probably noteworthy about
>> Ruby's #inject:
>>
>> It does matter whether you provide an argument or not:
>>
>> irb(main):001:0> (1..5).inject {|*a| p a; nil}
>> [1, 2]
>> [nil, 3]
>> [nil, 4]
>> [nil, 5]
>> => nil
>> irb(main):002:0> (1..5).inject(0) {|*a| p a; nil}
>> [0, 1]
>> [nil, 2]
>> [nil, 3]
>> [nil, 4]
>> [nil, 5]
>> => nil
>>
>> This means that when summing up you usually want to provide 0 as argument.
>>        >>
>> irb(main):003:0> (1..5).inject(0) {|sum,x| sum + x}
>> => 15
>> irb(main):004:0> [].inject(0) {|sum,x| sum + x}
>> => 0
>>
>> Whithout you do not get a sum for the empty collection:
>>
>> irb(main):005:0> [].inject {|sum,x| sum + x}
>> => nil
>
> Which you may or may not want.

I'd say normally you want 0 for an empty collection because that is
the neutral element for addition.  Any code relying on uniform further
processing of the result of summing up the collection will be simpler
if 0 is injected for the sum.

> I'm not sure I see the logic of why you example alone leads to the
> recommendation to provide the 0 argument:

Because the empty Enumerable is the one where behavior differs.

> ruby-1.8.7-p174 > (1..5).inject(0) {|sum,x| p [sum, x]; sum + x}
> [0, 1]
> [1, 2]
> [3, 3]
> [6, 4]
> [10, 5]
> > 15
> ruby-1.8.7-p174 > (1..5).inject {|sum,x| p [sum, x]; sum + x}
> [1, 2]
> [3, 3]
> [6, 4]
> [10, 5]
> > 15
>
> I've come to use inject or reduce depending on whether or not I'm
> providing the argument, assuming I'm using a version of Ruby which
> aliases them.        > mysterious, because that argument is what you are injecting.
>
> I think that most languages which have a form of reduce don't allow
> that argument, as far as I know, it came from Smaltalk whose form of
> reduce came from the inject:initialValue into: aBlock method on
> collection classes. For an old Smaltalker Ruby's inject was no
> mystery, but using reduce when not supplying the argument makes more
> sense to me.

So you are basically saying that you pick the method name depending on
whether you provide an argument or not.  Actually I had forgotten
about #reduce completely.  OTOH I use the method rarely nowadays but
when I use it I provide an argument most of the time.

Kind regards

robert

PS: Your posting was somehow cut off on my news server.  Does anybody
else experience the same?  The cut was after

> This means that when summing up you usually want to provide 0 as argument

(~ line 40)

-- 
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/