2

Why does [].sum gives an undefined method error?

[5, 15, 10].sum 
# => NoMethodError: undefined method `sum' for [5, 15, 10]:Array 

Doing ri Array#sum returns:

Array#sum

(from gem activesupport-4.2.6) Implementation from Enumerable
------------------------------------------------------------------------------
sum(identity = 0, &block)

------------------------------------------------------------------------------

Calculates a sum from the elements.

payments.sum { |p| p.price * p.tax_rate } payments.sum(&:price)

The latter is a shortcut for:

payments.inject(0) { |sum, p| sum + p.price }

It can also calculate the sum without the use of a block.

[5, 15, 10].sum # => 30                         ## <-- What?! >:(  
['foo', 'bar'].sum # => "foobar"
[[1, 2], [3, 1, 5]].sum => [1, 2, 3, 1, 5]

The default sum of an empty list is zero. You can override this default:

[].sum(Payment.new(0)) { |i| i.amount } # => Payment.new(0)

What's going on? What am I failing to understand? Or is my installation broken?

5

It mentions (from gem activesupport-4.2.6) Implementation from Enumerable.

require 'active_support'
require 'active_support/core_ext'

2.2.2 > [5, 15, 10].sum
=> 30
  • Ah. So it does. I guess I didn't understand the significance of that bit. – Jon Carter Jun 5 '16 at 23:26
  • So the problem was that I didn't understand the docs. Thanks again. But I'd like to understand this better. It seems to me that sum() should be there as natively as max() is. What's the rationalization? More technically, how is this implemented? Are there different Enumerable modules? Or.. it's a guess, but I suppose that active_support adds that method (and perhaps others) to Enumerable. Maybe I can look, if I can find the source. Can anyone suggest some further reading? Is there a programmatic way to examine these things? Like, "Show me the inheritance chain of this method." – Jon Carter Jun 5 '16 at 23:33
  • 1
    [].method(:sum).source_location will point to the file used – floum Jun 5 '16 at 23:37
  • Nice! That's going to be useful. :) – Jon Carter Jun 5 '16 at 23:41
  • 1
    The rationale behind it I'm not exactly sure, you could always write [5, 15, 10].reduce(:+) instead. It might be a good idea to look at the source code for Active Support Enumerable. Active Support adds a lot of useful extensions in general to Ruby, however beware that some things might seem like complete black magic such as Time.now + 5.send('days') (and you have to dig through a lot of source to find out how it's done). – Nabeel Jun 5 '16 at 23:46
1

Its already stated above in most answers that sum is not an instance method of array.

You can see all methods available on an object using object.methods. example [1,2,3].methods. Also you can refer to http://apidock.com/ruby/Array

[1,2,3].inject(0) {|sum,x| sum + x }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.