---
title: "Ruby 2.4 implements Enumerable#sum"
description:
  "In Ruby 2.4, every object belonging to the `Enumerable` family can now call
  `sum` method on it"
canonical_url: "https://www.bigbinary.com/blog/ruby-2-4-introduces-enumerable-sum"
markdown_url: "https://www.bigbinary.com/blog/ruby-2-4-introduces-enumerable-sum.md"
---

# Ruby 2.4 implements Enumerable#sum

In Ruby 2.4, every object belonging to the `Enumerable` family can now call
`sum` method on it

- Author: Mohit Natoo
- Published: November 2, 2016
- Categories: Ruby 2.4, Ruby

It is a common use case to calculate sum of the elements of an array or values
from a hash.

```ruby

[1, 2, 3, 4] => 10

{a: 1, b: 6, c: -3} => 4

```

Active Support already implements
[Enumerable#sum](https://github.com/rails/rails/blob/3d716b9e66e334c113c98fb3fc4bcf8a945b93a1/activesupport/lib/active_support/core_ext/enumerable.rb#L2-L27)

```ruby

> [1, 2, 3, 4].sum
 #=> 10

> {a: 1, b: 6, c: -3}.sum{ |k, v| v**2 }
 #=> 46

> ['foo', 'bar'].sum # concatenation of strings
 #=> "foobar"

> [[1], ['abc'], [6, 'qwe']].sum # concatenation of arrays
 #=> [1, "abc", 6, "qwe"]

```

Until Ruby 2.3, we had to use Active Support to use `Enumerable#sum` method or
we could use `#inject` which is
[used by Active Support under the hood](https://github.com/rails/rails/blob/3d716b9e66e334c113c98fb3fc4bcf8a945b93a1/activesupport/lib/active_support/core_ext/enumerable.rb#L2-L27).

Ruby 2.4.0 implements
[Enumerable#sum](https://github.com/ruby/ruby/commit/41ef7ec381338a97d15a6b4b18acd8b426a9ce79)
as [part of the language](https://bugs.ruby-lang.org/issues/12217) itself.

Let's take a look at how `sum` method fares on some of the enumerable objects in
Ruby 2.4.

```ruby

> [1, 2, 3, 4].sum
 #=> 10

> {a: 1, b: 6, c: -3}.sum { |k, v| v**2 }
 #=> 46

> ['foo', 'bar'].sum
 #=> TypeError: String can't be coerced into Integer

> [[1], ['abc'], [6, 'qwe']].sum
 #=> TypeError: Array can't be coerced into Integer

```

As we can see, the behavior of `Enumerable#sum` from Ruby 2.4 is same as that of
Active Support in case of numbers but not the same in case of string or array
concatenation. Let's see what is the difference and how we can make it work in
Ruby 2.4 as well.

### Understanding addition/concatenation identity

The `Enumerable#sum` method takes an optional argument which acts as an
accumulator. Both Active Support and Ruby 2.4 accept this argument.

When identity argument is not passed, `0` is used as default accumulator in Ruby
2.4 whereas Active Support uses `nil` as default accumulator.

Hence in the cases of string and array concatenation, the error occurred in Ruby
because the code attempts to add a string and array respectively to `0`.

To overcome this, we need to pass proper addition/concatenation identity as an
argument to the `sum` method.

The addition/concatenation identity of an object can be defined as the value
with which calling `+` operation on an object returns the same object.

```ruby

> ['foo', 'bar'].sum('')
 #=> "foobar"

> [[1], ['abc'], [6, 'qwe']].sum([])
 #=> [1, "abc", 6, "qwe"]

```

### What about Rails ?

As we have seen earlier, Ruby 2.4 implements `Enumerable#sum` favouring numeric
operations whereas also supporting non-numeric callers with the identity
element. This behavior is not entirely same as that of Active Support. But still
Active Support can make use of the native sum method whenever possible. There is
already a [pull request](https://github.com/rails/rails/pull/25202) open which
uses `Enumerable#sum` from Ruby whenever possible. This will help gain some
performance boost as the Ruby's method is implemented natively in C whereas that
in Active Support is implemented in Ruby.

## Links

- [Human page](https://www.bigbinary.com/blog/ruby-2-4-introduces-enumerable-sum)
