Method: Enumerable#sum

Defined in:
enum.c

#sum(initial_value = 0) ⇒ Numeric #sum(initial_value = 0) {|element| ... } ⇒ Object

With no block given, returns the sum of initial_value and the elements:

(1..100).sum          # => 5050
(1..100).sum(1)       # => 5051
('a'..'d').sum('foo') # => "fooabcd"

Generally, the sum is computed using methods + and each; for performance optimizations, those methods may not be used, and so any redefinition of those methods may not have effect here.

One such optimization: When possible, computes using Gauss’s summation formula n(n+1)/2:

100 * (100 + 1) / 2 # => 5050

With a block given, calls the block with each element; returns the sum of initial_value and the block return values:

(1..4).sum {|i| i*i }                        # => 30
(1..4).sum(100) {|i| i*i }                   # => 130
h = {a: 0, b: 1, c: 2, d: 3, e: 4, f: 5}
h.sum {|key, value| value.odd? ? value : 0 } # => 9
('a'..'f').sum('x') {|c| c < 'd' ? c : '' }  # => "xabc"

Overloads:

  • #sum(initial_value = 0) ⇒ Numeric

    Returns:

  • #sum(initial_value = 0) {|element| ... } ⇒ Object

    Yields:

    • (element)

    Returns:



4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
# File 'enum.c', line 4806

static VALUE
enum_sum(int argc, VALUE* argv, VALUE obj)
{
    struct enum_sum_memo memo;
    VALUE beg, end;
    int excl;

    memo.v = (rb_check_arity(argc, 0, 1) == 0) ? LONG2FIX(0) : argv[0];
    memo.block_given = rb_block_given_p();
    memo.n = 0;
    memo.r = Qundef;

    if ((memo.float_value = RB_FLOAT_TYPE_P(memo.v))) {
        memo.f = RFLOAT_VALUE(memo.v);
        memo.c = 0.0;
    }
    else {
        memo.f = 0.0;
        memo.c = 0.0;
    }

    if (RTEST(rb_range_values(obj, &beg, &end, &excl))) {
        if (!memo.block_given && !memo.float_value &&
                (FIXNUM_P(beg) || RB_BIGNUM_TYPE_P(beg)) &&
                (FIXNUM_P(end) || RB_BIGNUM_TYPE_P(end))) {
            return int_range_sum(beg, end, excl, memo.v);
        }
    }

    if (RB_TYPE_P(obj, T_HASH) &&
            rb_method_basic_definition_p(CLASS_OF(obj), id_each))
        hash_sum(obj, &memo);
    else
        rb_block_call(obj, id_each, 0, 0, enum_sum_i, (VALUE)&memo);

    if (memo.float_value) {
        return DBL2NUM(memo.f + memo.c);
    }
    else {
        if (memo.n != 0)
            memo.v = rb_fix_plus(LONG2FIX(memo.n), memo.v);
        if (!UNDEF_P(memo.r)) {
            memo.v = rb_rational_plus(memo.r, memo.v);
        }
        return memo.v;
    }
}