diff --git a/README.md b/README.md index 7408d31..852d285 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,9 @@ require 'enumerable/statistics' The following methods are supplied by this library: +- `Array#sum`, `Enumerable#sum` + - Calculates a sum of values in an array or an enumerable + - Supports `skip_na: true` to skip `nil` and `NaN` values - `Array#mean`, `Enumerable#mean` - Calculates a mean of values in an array or an enumerable - `Array#variance`, `Enumerable#variance` diff --git a/ext/enumerable/statistics/extension/statistics.c b/ext/enumerable/statistics/extension/statistics.c index 63b559c..3006fdf 100644 --- a/ext/enumerable/statistics/extension/statistics.c +++ b/ext/enumerable/statistics/extension/statistics.c @@ -103,7 +103,7 @@ static VALUE sym_auto, sym_left, sym_right, sym_sturges; static VALUE cHistogram; -static VALUE orig_enum_sum, orig_ary_sum; +static ID id_builtin_sum; inline static VALUE f_add(VALUE x, VALUE y) @@ -800,7 +800,7 @@ ary_calculate_sum(VALUE ary, VALUE init, int skip_na, long *na_count_out) * [Kahan summation algorithm](https://en.wikipedia.org/wiki/Kahan_summation_algorithm) * to compensate the result precision when the `ary` includes Float values. * - * Note that This library does not redefine `sum` method introduced in Ruby 2.4. + * Redefines `sum` (Ruby >= 2.4). Original is aliased as `__sum__`. * * @return [Number] A summation value */ @@ -817,7 +817,7 @@ ary_sum(int argc, VALUE* argv, VALUE ary) #ifndef HAVE_ENUM_SUM if (!skip_na) { - return rb_funcall(orig_ary_sum, rb_intern("call"), argc, &v); + return rb_funcall(ary, id_builtin_sum, argc, &v); } #endif @@ -1263,7 +1263,7 @@ enum_sum_count(VALUE obj, VALUE init, int skip_na, VALUE *sum_ptr, long *count_p * [Kahan summation algorithm](https://en.wikipedia.org/wiki/Kahan_summation_algorithm) * to compensate the result precision when the `enum` includes Float values. * - * Note that This library does not redefine `sum` method introduced in Ruby 2.4. + * Redefines `sum` (Ruby >= 2.4). Original is aliased as `__sum__`. * * @return [Number] A summation value */ @@ -1283,7 +1283,7 @@ enum_sum(int argc, VALUE* argv, VALUE obj) enum_sum_count(obj, init, skip_na, &sum, NULL); } else { - rb_funcall(orig_enum_sum, rb_intern("call"), argc, &init); + sum = rb_funcall(obj, id_builtin_sum, argc, &init); } #else enum_sum_count(obj, init, skip_na, &sum, NULL); @@ -2530,9 +2530,9 @@ Init_extension(void) mEnumerableStatistics = rb_const_get_at(rb_cObject, rb_intern("EnumerableStatistics")); - orig_enum_sum = rb_funcall(rb_mEnumerable, rb_intern("public_instance_method"), 1, rb_str_new_cstr("sum")); - orig_ary_sum = rb_funcall(rb_cArray, rb_intern("public_instance_method"), 1, rb_str_new_cstr("sum")); + id_builtin_sum = rb_intern("__sum__"); + rb_define_alias(rb_mEnumerable, "__sum__", "sum"); rb_define_method(rb_mEnumerable, "sum", enum_sum, -1); rb_define_method(rb_mEnumerable, "mean_variance", enum_mean_variance_m, -1); rb_define_method(rb_mEnumerable, "mean", enum_mean, 0); @@ -2541,6 +2541,7 @@ Init_extension(void) rb_define_method(rb_mEnumerable, "stdev", enum_stdev, -1); rb_define_method(rb_mEnumerable, "value_counts", enum_value_counts, -1); + rb_define_alias(rb_cArray, "__sum__", "sum"); rb_define_method(rb_cArray, "sum", ary_sum, -1); rb_define_method(rb_cArray, "mean_variance", ary_mean_variance_m, -1); rb_define_method(rb_cArray, "mean", ary_mean, -1);