Movatterモバイル変換


[0]ホーム

URL:


HomeClassesMethods

In Files

  • enumerator.c

Parent

Enumerator

Methods

Files

Class/Module Index[+]

Quicksearch
No matching classes.

Enumerator::ArithmeticSequence

Enumerator::ArithmeticSequence is asubclass ofEnumerator, that is arepresentation of sequences of numbers with common difference. Instances ofthis class can be generated by theRange#step andNumeric#step methods.

The class can be used for slicingArray (seeArray#slice) or custom collections.

Public Instance Methods

aseq == obj → true or falseclick to toggle source

Returnstrue only ifobj is anEnumerator::ArithmeticSequence, hasequivalent begin, end, step, and exclude_end? settings.

                static VALUEarith_seq_eq(VALUE self, VALUE other){    if (!RTEST(rb_obj_is_kind_of(other, rb_cArithSeq))) {        return Qfalse;    }    if (!rb_equal(arith_seq_begin(self), arith_seq_begin(other))) {        return Qfalse;    }    if (!rb_equal(arith_seq_end(self), arith_seq_end(other))) {        return Qfalse;    }    if (!rb_equal(arith_seq_step(self), arith_seq_step(other))) {        return Qfalse;    }    if (arith_seq_exclude_end_p(self) != arith_seq_exclude_end_p(other)) {        return Qfalse;    }    return Qtrue;}
aseq == obj → true or falseclick to toggle source

Returnstrue only ifobj is anEnumerator::ArithmeticSequence, hasequivalent begin, end, step, and exclude_end? settings.

                static VALUEarith_seq_eq(VALUE self, VALUE other){    if (!RTEST(rb_obj_is_kind_of(other, rb_cArithSeq))) {        return Qfalse;    }    if (!rb_equal(arith_seq_begin(self), arith_seq_begin(other))) {        return Qfalse;    }    if (!rb_equal(arith_seq_end(self), arith_seq_end(other))) {        return Qfalse;    }    if (!rb_equal(arith_seq_step(self), arith_seq_step(other))) {        return Qfalse;    }    if (arith_seq_exclude_end_p(self) != arith_seq_exclude_end_p(other)) {        return Qfalse;    }    return Qtrue;}
begin()click to toggle source
                inline VALUEarith_seq_begin(VALUE self){    return rb_ivar_get(self, id_begin);}
each {|i| block } → aseqclick to toggle source
each → aseq
                static VALUEarith_seq_each(VALUE self){    VALUE c, e, s, len_1, last;    int x;    if (!rb_block_given_p()) return self;    c = arith_seq_begin(self);    e = arith_seq_end(self);    s = arith_seq_step(self);    x = arith_seq_exclude_end_p(self);    if (!RB_TYPE_P(s, T_COMPLEX) && ruby_float_step(c, e, s, x, TRUE)) {        return self;    }    if (NIL_P(e)) {        while (1) {            rb_yield(c);            c = rb_int_plus(c, s);        }        return self;    }    if (rb_equal(s, INT2FIX(0))) {        while (1) {            rb_yield(c);        }        return self;    }    len_1 = num_idiv(num_minus(e, c), s);    last = num_plus(c, num_mul(s, len_1));    if (x && rb_equal(last, e)) {        last = num_minus(last, s);    }    if (rb_num_negative_int_p(s)) {        while (NUM_GE(c, last)) {            rb_yield(c);            c = num_plus(c, s);        }    }    else {        while (NUM_GE(last, c)) {            rb_yield(c);            c = num_plus(c, s);        }    }    return self;}
end()click to toggle source
                inline VALUEarith_seq_end(VALUE self){    return rb_ivar_get(self, id_end);}
aseq == obj → true or falseclick to toggle source

Returnstrue only ifobj is anEnumerator::ArithmeticSequence, hasequivalent begin, end, step, and exclude_end? settings.

                static VALUEarith_seq_eq(VALUE self, VALUE other){    if (!RTEST(rb_obj_is_kind_of(other, rb_cArithSeq))) {        return Qfalse;    }    if (!rb_equal(arith_seq_begin(self), arith_seq_begin(other))) {        return Qfalse;    }    if (!rb_equal(arith_seq_end(self), arith_seq_end(other))) {        return Qfalse;    }    if (!rb_equal(arith_seq_step(self), arith_seq_step(other))) {        return Qfalse;    }    if (arith_seq_exclude_end_p(self) != arith_seq_exclude_end_p(other)) {        return Qfalse;    }    return Qtrue;}
exclude_end?()click to toggle source
                inline VALUEarith_seq_exclude_end(VALUE self){    return rb_ivar_get(self, id_exclude_end);}
first → num or nilclick to toggle source
first(n) → an_array

Returns the first number in this arithmetic sequence, or an array of thefirstn elements.

                static VALUEarith_seq_first(int argc, VALUE *argv, VALUE self){    VALUE b, e, s, ary;    long n;    int x;    rb_check_arity(argc, 0, 1);    b = arith_seq_begin(self);    e = arith_seq_end(self);    s = arith_seq_step(self);    if (argc == 0) {        if (NIL_P(b)) {            return Qnil;        }        if (!NIL_P(e)) {            VALUE zero = INT2FIX(0);            int r = rb_cmpint(rb_num_coerce_cmp(s, zero, idCmp), s, zero);            if (r > 0 && RTEST(rb_funcall(b, '>', 1, e))) {                return Qnil;            }            if (r < 0 && RTEST(rb_funcall(b, '<', 1, e))) {                return Qnil;            }        }        return b;    }    // TODO: the following code should be extracted as arith_seq_take    n = NUM2LONG(argv[0]);    if (n < 0) {        rb_raise(rb_eArgError, "attempt to take negative size");    }    if (n == 0) {        return rb_ary_new_capa(0);    }    x = arith_seq_exclude_end_p(self);    if (FIXNUM_P(b) && NIL_P(e) && FIXNUM_P(s)) {        long i = FIX2LONG(b), unit = FIX2LONG(s);        ary = rb_ary_new_capa(n);        while (n > 0 && FIXABLE(i)) {            rb_ary_push(ary, LONG2FIX(i));            i += unit;  // FIXABLE + FIXABLE never overflow;            --n;        }        if (n > 0) {            b = LONG2NUM(i);            while (n > 0) {                rb_ary_push(ary, b);                b = rb_big_plus(b, s);                --n;            }        }        return ary;    }    else if (FIXNUM_P(b) && FIXNUM_P(e) && FIXNUM_P(s)) {        long i = FIX2LONG(b);        long end = FIX2LONG(e);        long unit = FIX2LONG(s);        long len;        if (unit >= 0) {            if (!x) end += 1;            len = end - i;            if (len < 0) len = 0;            ary = rb_ary_new_capa((n < len) ? n : len);            while (n > 0 && i < end) {                rb_ary_push(ary, LONG2FIX(i));                if (i + unit < i) break;                i += unit;                --n;            }        }        else {            if (!x) end -= 1;            len = i - end;            if (len < 0) len = 0;            ary = rb_ary_new_capa((n < len) ? n : len);            while (n > 0 && i > end) {                rb_ary_push(ary, LONG2FIX(i));                if (i + unit > i) break;                i += unit;                --n;            }        }        return ary;    }    else if (RB_FLOAT_TYPE_P(b) || RB_FLOAT_TYPE_P(e) || RB_FLOAT_TYPE_P(s)) {        /* generate values like ruby_float_step */        double unit = NUM2DBL(s);        double beg = NUM2DBL(b);        double end = NIL_P(e) ? (unit < 0 ? -1 : 1)*HUGE_VAL : NUM2DBL(e);        double len = ruby_float_step_size(beg, end, unit, x);        long i;        if (n > len)            n = (long)len;        if (isinf(unit)) {            if (len > 0) {                ary = rb_ary_new_capa(1);                rb_ary_push(ary, DBL2NUM(beg));            }            else {                ary = rb_ary_new_capa(0);            }        }        else if (unit == 0) {            VALUE val = DBL2NUM(beg);            ary = rb_ary_new_capa(n);            for (i = 0; i < len; ++i) {                rb_ary_push(ary, val);            }        }        else {            ary = rb_ary_new_capa(n);            for (i = 0; i < n; ++i) {                double d = i*unit+beg;                if (unit >= 0 ? end < d : d < end) d = end;                rb_ary_push(ary, DBL2NUM(d));            }        }        return ary;    }    return rb_call_super(argc, argv);}
hash → integerclick to toggle source

Compute a hash-value for this arithmetic sequence. Two arithmetic sequenceswith same begin, end, step, and exclude_end? values will generate the samehash-value.

See alsoObject#hash.

                static VALUEarith_seq_hash(VALUE self){    st_index_t hash;    VALUE v;    hash = rb_hash_start(arith_seq_exclude_end_p(self));    v = rb_hash(arith_seq_begin(self));    hash = rb_hash_uint(hash, NUM2LONG(v));    v = rb_hash(arith_seq_end(self));    hash = rb_hash_uint(hash, NUM2LONG(v));    v = rb_hash(arith_seq_step(self));    hash = rb_hash_uint(hash, NUM2LONG(v));    hash = rb_hash_end(hash);    return ST2FIX(hash);}
inspect → stringclick to toggle source

Convert this arithmetic sequence to a printable form.

                static VALUEarith_seq_inspect(VALUE self){    struct enumerator *e;    VALUE eobj, str, eargs;    int range_p;    TypedData_Get_Struct(self, struct enumerator, &enumerator_data_type, e);    eobj = rb_attr_get(self, id_receiver);    if (NIL_P(eobj)) {        eobj = e->obj;    }    range_p = RTEST(rb_obj_is_kind_of(eobj, rb_cRange));    str = rb_sprintf("(%s%"PRIsVALUE"%s.", range_p ? "(" : "", eobj, range_p ? ")" : "");    rb_str_buf_append(str, rb_id2str(e->meth));    eargs = rb_attr_get(eobj, id_arguments);    if (NIL_P(eargs)) {        eargs = e->args;    }    if (eargs != Qfalse) {        long argc = RARRAY_LEN(eargs);        const VALUE *argv = RARRAY_CONST_PTR(eargs); /* WB: no new reference */        if (argc > 0) {            VALUE kwds = Qnil;            rb_str_buf_cat2(str, "(");            if (RB_TYPE_P(argv[argc-1], T_HASH)) {                int all_key = TRUE;                rb_hash_foreach(argv[argc-1], key_symbol_p, (VALUE)&all_key);                if (all_key) kwds = argv[--argc];            }            while (argc--) {                VALUE arg = *argv++;                rb_str_append(str, rb_inspect(arg));                rb_str_buf_cat2(str, ", ");            }            if (!NIL_P(kwds)) {                rb_hash_foreach(kwds, kwd_append, str);            }            rb_str_set_len(str, RSTRING_LEN(str)-2); /* drop the last ", " */            rb_str_buf_cat2(str, ")");        }    }    rb_str_buf_cat2(str, ")");    return str;}
last → num or nilclick to toggle source
last(n) → an_array

Returns the last number in this arithmetic sequence, or an array of thelastn elements.

                static VALUEarith_seq_last(int argc, VALUE *argv, VALUE self){    VALUE b, e, s, len_1, len, last, nv, ary;    int last_is_adjusted;    long n;    e = arith_seq_end(self);    if (NIL_P(e)) {        rb_raise(rb_eRangeError,                 "cannot get the last element of endless arithmetic sequence");    }    b = arith_seq_begin(self);    s = arith_seq_step(self);    len_1 = num_idiv(num_minus(e, b), s);    if (rb_num_negative_int_p(len_1)) {        if (argc == 0) {            return Qnil;        }        return rb_ary_new_capa(0);    }    last = num_plus(b, num_mul(s, len_1));    if ((last_is_adjusted = arith_seq_exclude_end_p(self) && rb_equal(last, e))) {        last = num_minus(last, s);    }    if (argc == 0) {        return last;    }    if (last_is_adjusted) {        len = len_1;    }    else {        len = rb_int_plus(len_1, INT2FIX(1));    }    rb_scan_args(argc, argv, "1", &nv);    if (!RB_INTEGER_TYPE_P(nv)) {        nv = rb_to_int(nv);    }    if (RTEST(rb_int_gt(nv, len))) {        nv = len;    }    n = NUM2LONG(nv);    if (n < 0) {        rb_raise(rb_eArgError, "negative array size");    }    ary = rb_ary_new_capa(n);    b = rb_int_minus(last, rb_int_mul(s, nv));    while (n) {        b = rb_int_plus(b, s);        rb_ary_push(ary, b);        --n;    }    return ary;}
size → num or nilclick to toggle source

Returns the number of elements in this arithmetic sequence if it is afinite sequence. Otherwise, returnsnil.

                static VALUEarith_seq_size(VALUE self){    VALUE b, e, s, len_1, len, last;    int x;    b = arith_seq_begin(self);    e = arith_seq_end(self);    s = arith_seq_step(self);    x = arith_seq_exclude_end_p(self);    if (RB_FLOAT_TYPE_P(b) || RB_FLOAT_TYPE_P(e) || RB_FLOAT_TYPE_P(s)) {        double ee, n;        if (NIL_P(e)) {            if (rb_num_negative_int_p(s)) {                ee = -HUGE_VAL;            }            else {                ee = HUGE_VAL;            }        }        else {            ee = NUM2DBL(e);        }        n = ruby_float_step_size(NUM2DBL(b), ee, NUM2DBL(s), x);        if (isinf(n)) return DBL2NUM(n);        if (POSFIXABLE(n)) return LONG2FIX((long)n);        return rb_dbl2big(n);    }    if (NIL_P(e)) {        return DBL2NUM(HUGE_VAL);    }    if (!rb_obj_is_kind_of(s, rb_cNumeric)) {        s = rb_to_int(s);    }    if (rb_equal(s, INT2FIX(0))) {        return DBL2NUM(HUGE_VAL);    }    len_1 = rb_int_idiv(rb_int_minus(e, b), s);    if (rb_num_negative_int_p(len_1)) {        return INT2FIX(0);    }    last = rb_int_plus(b, rb_int_mul(s, len_1));    if (x && rb_equal(last, e)) {        len = len_1;    }    else {        len = rb_int_plus(len_1, INT2FIX(1));    }    return len;}
step()click to toggle source
                inline VALUEarith_seq_step(VALUE self){    return rb_ivar_get(self, id_step);}

This page was generated for Ruby 3.0.0

Generated with Ruby-doc Rdoc Generator 0.42.0.


[8]ページ先頭

©2009-2025 Movatter.jp