/*
* call-seq:
* enum.inject(initial) {| memo, obj | block } => obj
* enum.inject {| memo, obj | block } => obj
*
* Combines the elements of <i>enum</i> by applying the block to an
* accumulator value (<i>memo</i>) and each element in turn. At each
* step, <i>memo</i> is set to the value returned by the block. The
* first form lets you supply an initial value for <i>memo</i>. The
* second form uses the first element of the collection as a the
* initial value (and skips that element while iterating).
*
* # Sum some numbers
* (5..10).inject {|sum, n| sum + n } #=> 45
* # Multiply some numbers
* (5..10).inject(1) {|product, n| product * n } #=> 151200
*
* # find the longest word
* longest = %w{ cat sheep bear }.inject do |memo,word|
* memo.length > word.length ? memo : word
* end
* longest #=> "sheep"
*
* # find the length of the longest word
* longest = %w{ cat sheep bear }.inject(0) do |memo,word|
* memo >= word.length ? memo : word.length
* end
* longest #=> 5
*
*/
static VALUE
enum_inject(argc, argv, obj)
int argc;
VALUE *argv, obj;
{
NODE *memo;
VALUE n;
if (rb_scan_args(argc, argv, "01", &n) == 1) {
memo = rb_node_newnode(NODE_MEMO, n, Qfalse, 0);
}
else {
memo = rb_node_newnode(NODE_MEMO, Qnil, Qtrue, 0);
}
rb_iterate(rb_each, obj, inject_i, (VALUE)memo);
n = memo->u1.value;
rb_gc_force_recycle((VALUE)memo);
return n;
}