mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Lazy Enumerator reduce intermediate array creation
[ruby-core:87907] [Bug #14908] [Fix GH-1912] From: Anmol Chopra <chopraanmol1@gmail.com> git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64770 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
ec6c075702
commit
aefdd4e25f
2 changed files with 16 additions and 23 deletions
28
enumerator.c
28
enumerator.c
|
@ -107,7 +107,7 @@
|
||||||
*/
|
*/
|
||||||
VALUE rb_cEnumerator;
|
VALUE rb_cEnumerator;
|
||||||
static VALUE rb_cLazy;
|
static VALUE rb_cLazy;
|
||||||
static ID id_rewind, id_new, id_yield, id_to_enum;
|
static ID id_rewind, id_new, id_to_enum;
|
||||||
static ID id_next, id_result, id_receiver, id_arguments, id_memo, id_method, id_force;
|
static ID id_next, id_result, id_receiver, id_arguments, id_memo, id_method, id_force;
|
||||||
static ID id_begin, id_end, id_step, id_exclude_end;
|
static ID id_begin, id_end, id_step, id_exclude_end;
|
||||||
static VALUE sym_each, sym_cycle;
|
static VALUE sym_each, sym_cycle;
|
||||||
|
@ -1272,9 +1272,12 @@ yielder_yield(VALUE obj, VALUE args)
|
||||||
|
|
||||||
/* :nodoc: */
|
/* :nodoc: */
|
||||||
static VALUE
|
static VALUE
|
||||||
yielder_yield_push(VALUE obj, VALUE args)
|
yielder_yield_push(VALUE obj, VALUE arg)
|
||||||
{
|
{
|
||||||
yielder_yield(obj, args);
|
struct yielder *ptr = yielder_ptr(obj);
|
||||||
|
|
||||||
|
rb_proc_call_with_block(ptr->proc, 1, &arg, Qnil);
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1517,7 +1520,7 @@ lazy_init_yielder(VALUE val, VALUE m, int argc, VALUE *argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cont) {
|
if (cont) {
|
||||||
rb_funcall2(yielder, id_yield, 1, &(result->memo_value));
|
rb_funcall2(yielder, idLTLT, 1, &(result->memo_value));
|
||||||
}
|
}
|
||||||
if (LAZY_MEMO_BREAK_P(result)) {
|
if (LAZY_MEMO_BREAK_P(result)) {
|
||||||
rb_iter_break();
|
rb_iter_break();
|
||||||
|
@ -1829,7 +1832,9 @@ lazy_map(VALUE obj)
|
||||||
static VALUE
|
static VALUE
|
||||||
lazy_flat_map_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, yielder))
|
lazy_flat_map_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, yielder))
|
||||||
{
|
{
|
||||||
return rb_funcallv(yielder, id_yield, argc, argv);
|
VALUE arg = rb_enum_values_pack(argc, argv);
|
||||||
|
|
||||||
|
return rb_funcallv(yielder, idLTLT, 1, &arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
|
@ -1844,12 +1849,12 @@ lazy_flat_map_to_ary(VALUE obj, VALUE yielder)
|
||||||
{
|
{
|
||||||
VALUE ary = rb_check_array_type(obj);
|
VALUE ary = rb_check_array_type(obj);
|
||||||
if (NIL_P(ary)) {
|
if (NIL_P(ary)) {
|
||||||
rb_funcall(yielder, id_yield, 1, obj);
|
rb_funcall(yielder, idLTLT, 1, obj);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
long i;
|
long i;
|
||||||
for (i = 0; i < RARRAY_LEN(ary); i++) {
|
for (i = 0; i < RARRAY_LEN(ary); i++) {
|
||||||
rb_funcall(yielder, id_yield, 1, RARRAY_AREF(ary, i));
|
rb_funcall(yielder, idLTLT, 1, RARRAY_AREF(ary, i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Qnil;
|
return Qnil;
|
||||||
|
@ -1862,7 +1867,7 @@ lazy_flat_map_proc(RB_BLOCK_CALL_FUNC_ARGLIST(val, m))
|
||||||
if (RB_TYPE_P(result, T_ARRAY)) {
|
if (RB_TYPE_P(result, T_ARRAY)) {
|
||||||
long i;
|
long i;
|
||||||
for (i = 0; i < RARRAY_LEN(result); i++) {
|
for (i = 0; i < RARRAY_LEN(result); i++) {
|
||||||
rb_funcall(argv[0], id_yield, 1, RARRAY_AREF(result, i));
|
rb_funcall(argv[0], idLTLT, 1, RARRAY_AREF(result, i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -2060,7 +2065,7 @@ lazy_zip_arrays_func(RB_BLOCK_CALL_FUNC_ARGLIST(val, arrays))
|
||||||
for (i = 0; i < RARRAY_LEN(arrays); i++) {
|
for (i = 0; i < RARRAY_LEN(arrays); i++) {
|
||||||
rb_ary_push(ary, rb_ary_entry(RARRAY_AREF(arrays, i), count));
|
rb_ary_push(ary, rb_ary_entry(RARRAY_AREF(arrays, i), count));
|
||||||
}
|
}
|
||||||
rb_funcall(yielder, id_yield, 1, ary);
|
rb_funcall(yielder, idLTLT, 1, ary);
|
||||||
rb_ivar_set(yielder, id_memo, LONG2NUM(++count));
|
rb_ivar_set(yielder, id_memo, LONG2NUM(++count));
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
@ -2093,7 +2098,7 @@ lazy_zip_func(RB_BLOCK_CALL_FUNC_ARGLIST(val, zip_args))
|
||||||
rb_eStopIteration, (VALUE)0);
|
rb_eStopIteration, (VALUE)0);
|
||||||
rb_ary_push(ary, v);
|
rb_ary_push(ary, v);
|
||||||
}
|
}
|
||||||
rb_funcall(yielder, id_yield, 1, ary);
|
rb_funcall(yielder, idLTLT, 1, ary);
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2950,7 +2955,7 @@ InitVM_Enumerator(void)
|
||||||
rb_define_alloc_func(rb_cYielder, yielder_allocate);
|
rb_define_alloc_func(rb_cYielder, yielder_allocate);
|
||||||
rb_define_method(rb_cYielder, "initialize", yielder_initialize, 0);
|
rb_define_method(rb_cYielder, "initialize", yielder_initialize, 0);
|
||||||
rb_define_method(rb_cYielder, "yield", yielder_yield, -2);
|
rb_define_method(rb_cYielder, "yield", yielder_yield, -2);
|
||||||
rb_define_method(rb_cYielder, "<<", yielder_yield_push, -2);
|
rb_define_method(rb_cYielder, "<<", yielder_yield_push, 1);
|
||||||
|
|
||||||
/* ArithmeticSequence */
|
/* ArithmeticSequence */
|
||||||
rb_cArithSeq = rb_define_class_under(rb_cEnumerator, "ArithmeticSequence", rb_cEnumerator);
|
rb_cArithSeq = rb_define_class_under(rb_cEnumerator, "ArithmeticSequence", rb_cEnumerator);
|
||||||
|
@ -2978,7 +2983,6 @@ void
|
||||||
Init_Enumerator(void)
|
Init_Enumerator(void)
|
||||||
{
|
{
|
||||||
id_rewind = rb_intern("rewind");
|
id_rewind = rb_intern("rewind");
|
||||||
id_yield = rb_intern("yield");
|
|
||||||
id_new = rb_intern("new");
|
id_new = rb_intern("new");
|
||||||
id_next = rb_intern("next");
|
id_next = rb_intern("next");
|
||||||
id_result = rb_intern("result");
|
id_result = rb_intern("result");
|
||||||
|
|
|
@ -21,15 +21,4 @@ describe "Enumerator::Yielder#<<" do
|
||||||
y = Enumerator::Yielder.new {|x| x + 1}
|
y = Enumerator::Yielder.new {|x| x + 1}
|
||||||
(y << 1).should equal(y)
|
(y << 1).should equal(y)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "requires multiple arguments" do
|
|
||||||
Enumerator::Yielder.instance_method(:<<).arity.should < 0
|
|
||||||
end
|
|
||||||
|
|
||||||
it "yields with passed arguments" do
|
|
||||||
yields = []
|
|
||||||
y = Enumerator::Yielder.new {|*args| yields << args }
|
|
||||||
y.<<(1, 2)
|
|
||||||
yields.should == [[1, 2]]
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue