Class: Enumerator::ArithmeticSequence
| Relationships & Source Files | |
| Super Chains via Extension / Inclusion / Inheritance | |
| Class Chain: 
          self,
           ::Enumerator | |
| Instance Chain: 
          self,
           ::Enumerator,::Enumerable | |
| Inherits: | Enumerator 
 | 
| Defined in: | enumerator.c, enumerator.c | 
Overview
ArithmeticSequence is a subclass of ::Enumerator, that is a representation of sequences of numbers with common difference. Instances of this class can be generated by the Range#step and Numeric#step methods.
The class can be used for slicing ::Array (see Array#slice) or custom collections.
Class Method Summary
::Enumerator - Inherited
| .new | Creates a new  | 
| .produce | Creates an infinite enumerator from any block, just called over and over. | 
| .product | Generates a new enumerator object that generates a Cartesian product of given enumerable objects. | 
Instance Attribute Summary
- #exclude_end? ⇒ Boolean readonly
Instance Method Summary
- 
    
      #==(obj)  ⇒ Boolean 
      (also: #===, #eql?)
    
    Returns trueonly ifobjis anArithmeticSequence, has equivalent begin, end, step, and exclude_end? settings.
- 
    
      #===(obj)  ⇒ Boolean 
    
    Alias for #==. 
- #begin
- #end
- 
    
      #eql?(obj)  ⇒ Boolean 
    
    Alias for #==. 
- 
    
      #first  ⇒ Numeric? 
    
    Returns the first number in this arithmetic sequence, or an array of the first nelements.
- 
    
      #hash  ⇒ Integer 
    
    Compute a hash-value for this arithmetic sequence. 
- 
    
      #last  ⇒ Numeric? 
    
    Returns the last number in this arithmetic sequence, or an array of the last nelements.
- #step
::Enumerator - Inherited
| #+ | Returns an enumerator object generated from this enumerator and a given enumerable. | 
| #each | Iterates over the block according to how this  | 
| #each_with_index | Same as #with_index(0), i.e. there is no starting offset. | 
| #each_with_object | Alias for #with_object. | 
| #feed | Sets the value to be returned by the next yield inside  | 
| #inspect | Creates a printable version of e. | 
| #next | Returns the next object in the enumerator, and move the internal position forward. | 
| #next_values | Returns the next object as an array in the enumerator, and move the internal position forward. | 
| #peek | Returns the next object in the enumerator, but doesn’t move the internal position forward. | 
| #peek_values | Returns the next object as an array, similar to #next_values, but doesn’t move the internal position forward. | 
| #rewind | Rewinds the enumeration sequence to the beginning. | 
| #size | Returns the size of the enumerator, or  | 
| #with_index | Iterates the given block for each element with an index, which starts from  | 
| #with_object | Iterates the given block for each element with an arbitrary object,  | 
| #initialize_copy | |
::Enumerable - Included
| #all? | Returns whether every element meets a given criterion. | 
| #any? | Returns whether any element meets a given criterion. | 
| #chain | Returns an enumerator object generated from this enumerator and given enumerables. | 
| #chunk | Each element in the returned enumerator is a 2-element array consisting of: | 
| #chunk_while | Creates an enumerator for each chunked elements. | 
| #collect | Alias for Enumerable#map. | 
| #collect_concat | Alias for Enumerable#flat_map. | 
| #compact | Returns an array of all non- | 
| #count | Returns the count of elements, based on an argument or block criterion, if given. | 
| #cycle | When called with positive integer argument  | 
| #detect | Alias for Enumerable#find. | 
| #drop | For positive integer  | 
| #drop_while | Calls the block with successive elements as long as the block returns a truthy value; returns an array of all elements after that point: | 
| #each_cons | Calls the block with each successive overlapped  | 
| #each_entry | Calls the given block with each element, converting multiple values from yield to an array; returns  | 
| #each_slice | Calls the block with each successive disjoint  | 
| #each_with_index | With a block given, calls the block with each element and its index; returns  | 
| #each_with_object | Calls the block once for each element, passing both the element and the given object: | 
| #entries | Alias for Enumerable#to_a. | 
| #filter | Returns an array containing elements selected by the block. | 
| #filter_map | Returns an array containing truthy elements returned by the block. | 
| #find | Returns the first element for which the block returns a truthy value. | 
| #find_all | Alias for Enumerable#filter. | 
| #find_index | Returns the index of the first element that meets a specified criterion, or  | 
| #first | Returns the first element or elements. | 
| #flat_map | Returns an array of flattened objects returned by the block. | 
| #grep | Returns an array of objects based elements of  | 
| #grep_v | Returns an array of objects based on elements of  | 
| #group_by | With a block given returns a hash: | 
| #include? | Alias for Enumerable#member?. | 
| #inject | Returns an object formed from operands via either: | 
| #lazy | Returns an  | 
| #map | Returns an array of objects returned by the block. | 
| #max | Returns the element with the maximum element according to a given criterion. | 
| #max_by | Returns the elements for which the block returns the maximum values. | 
| #member? | Returns whether for any element  | 
| #min | Returns the element with the minimum element according to a given criterion. | 
| #min_by | Returns the elements for which the block returns the minimum values. | 
| #minmax | Returns a 2-element array containing the minimum and maximum elements according to a given criterion. | 
| #minmax_by | Returns a 2-element array containing the elements for which the block returns minimum and maximum values: | 
| #none? | Returns whether no element meets a given criterion. | 
| #one? | Returns whether exactly one element meets a given criterion. | 
| #partition | With a block given, returns an array of two arrays: | 
| #reduce | Alias for Enumerable#inject. | 
| #reject | Returns an array of objects rejected by the block. | 
| #reverse_each | With a block given, calls the block with each element, but in reverse order; returns  | 
| #select | Alias for Enumerable#filter. | 
| #slice_after | Creates an enumerator for each chunked elements. | 
| #slice_before | With argument  | 
| #slice_when | Creates an enumerator for each chunked elements. | 
| #sort | Returns an array containing the sorted elements of  | 
| #sort_by | With a block given, returns an array of elements of  | 
| #sum | With no block given, returns the sum of  | 
| #take | For non-negative integer  | 
| #take_while | Calls the block with successive elements as long as the block returns a truthy value; returns an array of all elements up to that point: | 
| #tally | Returns a hash containing the counts of equal elements: | 
| #to_a | Returns an array containing the items in  | 
| #to_h | When  | 
| #to_set | Makes a set from the enumerable object with given arguments. | 
| #uniq | With no block, returns a new array containing only unique elements; the array has no two elements  | 
| #zip | With no block given, returns a new array  | 
Constructor Details
This class inherits a constructor from Enumerator
Instance Attribute Details
    #exclude_end?  ⇒ Boolean  (readonly)
  
  [ GitHub ]
Instance Method Details
    #==(obj)  ⇒ Boolean     Also known as: #===, #eql?
  
Returns true only if obj is an ArithmeticSequence, has equivalent begin, end, step, and exclude_end? settings.
# File 'enumerator.c', line 4282
static VALUE
arith_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;
}
  
    
      #==(obj)  ⇒ Boolean 
      #===(obj)  ⇒ Boolean 
    
  
Boolean 
      #===(obj)  ⇒ Boolean 
    Alias for #==.
#begin
[ GitHub ]#end
[ GitHub ]
    
      #==(obj)  ⇒ Boolean 
      #eql?(obj)  ⇒ Boolean 
    
  
Boolean 
      #eql?(obj)  ⇒ Boolean 
    Alias for #==.
Returns the first number in this arithmetic sequence, or an array of the first n elements.
# File 'enumerator.c', line 3923
static VALUE
arith_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 ⇒ Integer
Compute a hash-value for this arithmetic sequence. Two arithmetic sequences with same begin, end, step, and exclude_end? values will generate the same hash-value.
See also Object#hash.
# File 'enumerator.c', line 4318
static VALUE
arith_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);
}
  Returns the last number in this arithmetic sequence, or an array of the last n elements.
# File 'enumerator.c', line 4149
static VALUE
arith_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;
}