[RUBY] Array # sum of ActiveSupport changes seven times

Active Support, which is always taken care of by Rails engineers, includes processing to extend the Ruby default Array # sum. Here is a summary of the behavior of #sum found when chasing the implementation of ActiveSupport in a certain library development.

[1,2,3].sum Probably the most standard usage.

[5, 15, 10].sum                                                                       
=> 3

By the way, this usage can be used without using ActiveSupport. In the past, it seems that ActiveSupport's Array # sum operated faster than Ruby's standard Array # sum, and it was taken into the head family at a certain time, and now both are said to be the same speed.

['foo', 'bar'].sum

An error will occur without Active Support ↓


pry(main)> ['foo', 'bar'].sum
TypeError: String can't be coerced into Integer
from (pry):1:in `+'

However, with Active Support, this happens

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

Suddenly + turned into Array.join. That said, it's not that you can't understand this behavior because you can concatenate strings by adding + in Ruby.

[[1,2,3], [4,5]].sum

As in the previous example, an error will occur without Active Support.

pry(main)> [[1,2,3], [4,5]].sum
TypeError: Array can't be coerced into Integer
from (pry):2:in `+'

So what happens with Active Support? It will be like this

pry(main)> [[1,2,3], [4,5]].sum
=> [1, 2, 3, 4, 5]

Perhaps some people expected it to behave the same as Array.flatten.sum? Unfortunately the result is not sum. It will be flatten instead. why...?

bonus

What if you sum with Hash instead of Array?

pry(main)> {a: 10, b: 20}.sum
=> [:a, 10, :b, 20]

!?!?!? Looking at the source code, I found the following description

  # We can't use Refinements here because Refinements with Module which will be prepended
  # doesn't work well https://bugs.ruby-lang.org/issues/13446

I see ...

Recommended Posts

Array # sum of ActiveSupport changes seven times
12 of Array