diff options
Diffstat (limited to 'enum.c')
-rw-r--r-- | enum.c | 40 |
1 files changed, 15 insertions, 25 deletions
@@ -491,23 +491,23 @@ zip_i(val, memo) VALUE val; NODE *memo; { - VALUE ary = memo->u1.value; - int i = memo->u3.cnt++; - int elen = memo->u2.argc+1; + VALUE result = memo->u1.value; + VALUE args = memo->u2.value; + int idx = memo->u3.cnt++; VALUE tmp; + int i; - if (i < RARRAY(ary)->len) { - tmp = RARRAY(ary)->ptr[i]; - RARRAY(tmp)->ptr[0] = val; + tmp = rb_ary_new2(RARRAY(args)->len + 1); + rb_ary_store(tmp, 0, val); + RARRAY(tmp)->ptr[0] = val; + for (i=0; i<RARRAY(args)->len; i++) { + rb_ary_push(tmp, rb_ary_entry(RARRAY(args)->ptr[i], idx)); + } + if (rb_block_given_p()) { + rb_yield(tmp); } else { - tmp = rb_ary_new2(elen); - RARRAY(tmp)->ptr[0] = val; - for (i=1; i<elen; i++) { - RARRAY(tmp)->ptr[i] = Qnil; - } - RARRAY(tmp)->len = elen; - rb_ary_push(ary, tmp); + rb_ary_push(result, tmp); } return Qnil; } @@ -525,19 +525,9 @@ enum_zip(argc, argv, obj) len = 0; for (i=0; i<argc; i++) { argv[i] = rb_convert_type(argv[i], T_ARRAY, "Array", "to_ary"); - if (RARRAY(argv[i])->len > len) len = RARRAY(argv[i])->len; - } - result = rb_ary_new2(len); - for (i=0; i<len; i++) { - VALUE tmp = rb_ary_new2(argc+1); - - rb_ary_push(tmp, Qnil); - for (j=0; j<argc; j++) { - rb_ary_push(tmp, rb_ary_entry(argv[j], i)); - } - rb_ary_push(result, tmp); } - memo = rb_node_newnode(NODE_MEMO, result, argc, 0); + result = rb_block_given_p() ? Qnil : rb_ary_new(); + memo = rb_node_newnode(NODE_MEMO, result, rb_ary_new4(argc, argv), 0); rb_iterate(rb_each, obj, zip_i, (VALUE)memo); return result; |