sum(p1 = v1)
public
Returns the sum of elements in an Enumerable.
If a block is given, the block is applied to each element before addition.
If enum is empty, it returns init.
For example:
{ 1 => 10, 2 => 20 }.sum {|k, v| k * v }
(1..10).sum
(1..10).sum {|v| v * 2 }
[Object.new].each.sum
This method can be used for non-numeric objects by explicit init
argument.
{ 1 => 10, 2 => 20 }.sum([])
"a\nb\nc".each_line.lazy.map(&:chomp).sum("")
Enumerable#sum method may not respect
method redefinition of “+” methods such as Integer#+.
static VALUE
enum_sum(int argc, VALUE* argv, VALUE obj)
{
struct enum_sum_memo memo;
VALUE beg, end;
int excl;
if (rb_scan_args(argc, argv, "01", &memo.v) == 0)
memo.v = LONG2FIX(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;
}
if (RTEST(rb_range_values(obj, &beg, &end, &excl))) {
if (!memo.block_given && !memo.float_value &&
(FIXNUM_P(beg) || RB_TYPE_P(beg, T_BIGNUM)) &&
(FIXNUM_P(end) || RB_TYPE_P(end, T_BIGNUM))) {
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 (memo.r != Qundef) {
/* r can be an Integer when mathn is loaded */
if (FIXNUM_P(memo.r))
memo.v = rb_fix_plus(memo.r, memo.v);
else if (RB_TYPE_P(memo.r, T_BIGNUM))
memo.v = rb_big_plus(memo.r, memo.v);
else
memo.v = rb_rational_plus(memo.r, memo.v);
}
return memo.v;
}
}