@mu слишком короткий: или, может быть, это означает «память».

y - сравни элегантно два счетчика, было сказаноПроблема с zip в том, что он создает массивы внутри, независимо от того, что Enumerable вы передаете. Есть еще одна проблема с длиной входных параметров

Я посмотрел на реализацию Enumerable # zip в YARV и увидел

Я правильно понимаю следующие биты?

static VALUE
enum_zip(int argc, VALUE *argv, VALUE obj)
{
    int i;
    ID conv;
    NODE *memo;
    VALUE result = Qnil;
    VALUE args = rb_ary_new4(argc, argv);
    int allary = TRUE;

    argv = RARRAY_PTR(args);
    for (i=0; i<argc; i++) {
        VALUE ary = rb_check_array_type(argv[i]);
        if (NIL_P(ary)) {
            allary = FALSE;
            break;
        }
        argv[i] = ary;
    }
    if (!allary) {
        CONST_ID(conv, "to_enum");
        for (i=0; i<argc; i++) {
            argv[i] = rb_funcall(argv[i], conv, 1, ID2SYM(id_each));
        }
    }
    if (!rb_block_given_p()) {
        result = rb_ary_new();
    }
    /* use NODE_DOT2 as memo(v, v, -) */
    memo = rb_node_newnode(NODE_DOT2, result, args, 0);
    rb_block_call(obj, id_each, 0, 0, allary ? zip_ary : zip_i, (VALUE)memo);

    return result;
}

Проверьте, являются ли все аргументы массивами, и если да, замените некоторую косвенную ссылку на массив прямой ссылкой

Если они не все массивы, вместо этого создайте перечислитель

    for (i=0; i<argc; i++) {
        VALUE ary = rb_check_array_type(argv[i]);
        if (NIL_P(ary)) {
            allary = FALSE;
            break;
        }
        argv[i] = ary;
    }

Создайте массив массивов, только если блок не указан

    if (!allary) {
        CONST_ID(conv, "to_enum");
        for (i=0; i<argc; i++) {
            argv[i] = rb_funcall(argv[i], conv, 1, ID2SYM(id_each));
        }
    }

Если все является массивом, используйте

    if (!rb_block_given_p()) {
        result = rb_ary_new();
    }

иначе используйтеzip_aryи вызвать блок для каждого набора значенийzip_iВернуть массив массивов, если блок не указан, иначе вернуть nil (

    /* use NODE_DOT2 as memo(v, v, -) */
    memo = rb_node_newnode(NODE_DOT2, result, args, 0);
    rb_block_call(obj, id_each, 0, 0, allary ? zip_ary : zip_i, (VALUE)memo);

)?QnilЯ буду использовать 1.9.2-p0, поскольку это то, что у меня под рукой.

    return result;
}

Ответы на вопрос(0)

Ваш ответ на вопрос