123456789_123456789_123456789_123456789_123456789_

Class: Enumerator::Lazy

Relationships & Source Files
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
self, ::Enumerator
Instance Chain:
Inherits: Enumerator
Defined in: enumerator.c

Overview

Lazy

Class Method Summary

::Enumerator - Inherited

.new

Creates a new ::Enumerator object, which can be used as an ::Enumerable.

Instance Method Summary

::Enumerator - Inherited

#each

Iterates over the block according to how this ::Enumerator was constructed.

#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 e.

#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 nil if it can't be calculated lazily.

#with_index

Iterates the given block for each element with an index, which starts from offset.

#with_object

Iterates the given block for each element with an arbitrary object, obj, and returns obj

#initialize_copy

::Enumerable - Included

#all?

Passes each element of the collection to the given block.

#any?

Passes each element of the collection to the given block.

#chunk

Enumerates over the items, chunking them together based on the return value of the block.

#chunk_while

Creates an enumerator for each chunked elements.

#collect

Alias for Enumerable#map.

#collect_concat
#count

Returns the number of items in enum through enumeration.

#cycle

Calls block for each element of enum repeatedly n times or forever if none or nil is given.

#detect

Alias for Enumerable#find.

#drop

Drops first n elements from enum, and returns rest elements in an array.

#drop_while

Drops elements up to, but not including, the first element for which the block returns nil or false and returns an array containing the remaining elements.

#each_cons

Iterates the given block for each array of consecutive <n> elements.

#each_entry

Calls block once for each element in self, passing that element as a parameter, converting multiple values from yield to an array.

#each_slice

Iterates the given block for each slice of <n> elements.

#each_with_index

Calls block with two arguments, the item and its index, for each item in enum.

#each_with_object

Iterates the given block for each element with an arbitrary object given, and returns the initially given object.

#entries

Alias for Enumerable#to_a.

#find

Passes each entry in enum to block.

#find_all
#find_index

Compares each entry in enum with value or passes to block.

#first

Returns the first element, or the first n elements, of the enumerable.

#flat_map

Returns a new array with the concatenated results of running block once for every element in enum.

#grep

Returns an array of every element in enum for which Pattern === element.

#grep_v

Inverted version of Enumerable#grep.

#group_by

Groups the collection by result of the block.

#include?
#inject

Combines all elements of enum by applying a binary operation, specified by a block or a symbol that names a method or operator.

#lazy

Returns a lazy enumerator, whose methods map/collect, flat_map/collect_concat, select/find_all, reject, grep, grep_v, zip, take, take_while, drop, and drop_while enumerate values only on an as-needed basis.

#map

Returns a new array with the results of running block once for every element in enum.

#max

Returns the object in enum with the maximum value.

#max_by

Returns the object in enum that gives the maximum value from the given block.

#member?

Returns true if any member of enum equals obj.

#min

Returns the object in enum with the minimum value.

#min_by

Returns the object in enum that gives the minimum value from the given block.

#minmax

Returns a two element array which contains the minimum and the maximum value in the enumerable.

#minmax_by

Returns a two element array containing the objects in enum that correspond to the minimum and maximum values respectively from the given block.

#none?

Passes each element of the collection to the given block.

#one?

Passes each element of the collection to the given block.

#partition

Returns two arrays, the first containing the elements of enum for which the block evaluates to true, the second containing the rest.

#reduce
#reject

Returns an array for all elements of enum for which the given block returns false.

#reverse_each

Builds a temporary array and traverses that array in reverse order.

#select

Returns an array containing all elements of enum for which the given block returns a true value.

#slice_after

Creates an enumerator for each chunked elements.

#slice_before

Creates an enumerator for each chunked elements.

#slice_when

Creates an enumerator for each chunked elements.

#sort

Returns an array containing the items in enum sorted.

#sort_by

Sorts enum using a set of keys generated by mapping the values in enum through the given block.

#sum

Returns the sum of elements in an ::Enumerable.

#take

Returns first n elements from enum.

#take_while

Passes elements to the block until the block returns nil or false, then stops iterating and returns an array of all prior elements.

#to_a

Returns an array containing the items in enum.

#to_h

Returns the result of interpreting enum as a list of [key, value] pairs.

#uniq

Returns a new array by removing duplicate values in self.

#zip

Takes one element from enum and merges corresponding elements from each args.

Constructor Details

.new(obj, size = nil) {|yielder, *values| ... }

Creates a new Lazy enumerator. When the enumerator is actually enumerated (e.g. by calling #force), obj will be enumerated and each value passed to the given block. The block can yield values back using yielder. For example, to create a method filter_map in both lazy and non-lazy fashions:

module Enumerable
  def filter_map(&block)
    map(&block).compact
  end
end

class Enumerator::Lazy
  def filter_map
    Lazy.new(self) do |yielder, *values|
      result = yield *values
      yielder << result if result
    end
  end
end

(1..Float::INFINITY).lazy.filter_map{|i| i*i if i.even?}.first(5)
    # => [4, 16, 36, 64, 100]
[ GitHub ]

  
# File 'enumerator.c', line 1551

static VALUE
lazy_initialize(int argc, VALUE *argv, VALUE self)
{
    VALUE obj, size = Qnil;
    VALUE generator;

    rb_check_arity(argc, 1, 2);
    if (!rb_block_given_p()) {
	rb_raise(rb_eArgError, "tried to call lazy new without a block");
    }
    obj = argv[0];
    if (argc > 1) {
	size = argv[1];
    }
    generator = generator_allocate(rb_cGenerator);
    rb_block_call(generator, id_initialize, 0, 0, lazy_init_block_i, obj);
    enumerator_init(self, generator, sym_each, 0, 0, 0, size);
    rb_ivar_set(self, id_receiver, obj);

    return self;
}

Instance Method Details

#chunk(*args) Also known as: #slice_before, #slice_after, #slice_when, #chunk_while

[ GitHub ]

  
# File 'enumerator.c', line 2277

static VALUE
lazy_super(int argc, VALUE *argv, VALUE lazy)
{
    return enumerable_lazy(rb_call_super(argc, argv));
}

#chunk_while(*args)

Alias for #chunk.

#collect

Alias for #map.

#collect_concat {|obj| ... } ⇒ Lazy #flat_map {|obj| ... } ⇒ Lazy

Alias for #flat_map.

#drop(n)

[ GitHub ]

  
# File 'enumerator.c', line 2188

static VALUE
lazy_drop(VALUE obj, VALUE n)
{
    long len = NUM2LONG(n);
    VALUE argv[2];
    argv[0] = sym_each;
    argv[1] = n;

    if (len < 0) {
	rb_raise(rb_eArgError, "attempt to drop negative size");
    }

    return lazy_add_method(obj, 2, argv, n, rb_ary_new3(1, n), &lazy_drop_funcs);
}

#drop_while

[ GitHub ]

  
# File 'enumerator.c', line 2225

static VALUE
lazy_drop_while(VALUE obj)
{
    if (!rb_block_given_p()) {
	rb_raise(rb_eArgError, "tried to call lazy drop_while without a block");
    }

    return lazy_add_method(obj, 0, 0, Qfalse, Qnil, &lazy_drop_while_funcs);
}

#to_enum(method = :each, *args) ⇒ Lazy #enum_for(method = :each, *args) ⇒ Lazy #to_enum(method = :each, *args) {|*args| ... } ⇒ Lazy #enum_for(method = :each, *args) {|*args| ... } ⇒ Lazy

Alias for #to_enum.

#find_all

Alias for #select.

#collect_concat {|obj| ... } ⇒ Lazy #flat_map {|obj| ... } ⇒ Lazy
Also known as: #collect_concat

Returns a new lazy enumerator with the concatenated results of running block once for every element in lazy.

["foo", "bar"].lazy.flat_map {|i| i.each_char.lazy}.force
#=> ["f", "o", "o", "b", "a", "r"]

A value x returned by block is decomposed if either of the following conditions is true:

a) <i>x</i> responds to both each and force, which means that
   <i>x</i> is a lazy enumerator.
b) <i>x</i> is an array or responds to to_ary.

Otherwise, x is contained as-is in the return value.

[{a:1}, {b:2}].lazy.flat_map {|i| i}.force
#=> [{:a=>1}, {:b=>2}]
[ GitHub ]

  
# File 'enumerator.c', line 1845

static VALUE
lazy_flat_map(VALUE obj)
{
    if (!rb_block_given_p()) {
	rb_raise(rb_eArgError, "tried to call lazy flat_map without a block");
    }

    return lazy_set_method(rb_block_call(rb_cLazy, id_new, 1, &obj,
					 lazy_flat_map_proc, 0),
			   Qnil, 0);
}

#force(*args) ⇒ Array

Alias for Enumerable#to_a.

#grep(pattern)

[ GitHub ]

  
# File 'enumerator.c', line 1932

static VALUE
lazy_grep(VALUE obj, VALUE pattern)
{
    const lazyenum_funcs *const funcs = rb_block_given_p() ?
	&lazy_grep_iter_funcs : &lazy_grep_funcs;
    return lazy_add_method(obj, 0, 0, pattern, rb_ary_new3(1, pattern), funcs);
}

#grep_v(pattern)

[ GitHub ]

  
# File 'enumerator.c', line 1964

static VALUE
lazy_grep_v(VALUE obj, VALUE pattern)
{
    return lazy_set_method(rb_block_call(rb_cLazy, id_new, 1, &obj,
					 rb_block_given_p() ?
					 lazy_grep_v_iter : lazy_grep_v_func,
					 pattern),
			   rb_ary_new3(1, pattern), 0);
}

#lazy

[ GitHub ]

  
# File 'enumerator.c', line 2283

static VALUE
lazy_lazy(VALUE obj)
{
    return obj;
}

#map Also known as: #collect

[ GitHub ]

  
# File 'enumerator.c', line 1762

static VALUE
lazy_map(VALUE obj)
{
    if (!rb_block_given_p()) {
	rb_raise(rb_eArgError, "tried to call lazy map without a block");
    }

    return lazy_add_method(obj, 0, 0, Qnil, Qnil, &lazy_map_funcs);
}

#reject

[ GitHub ]

  
# File 'enumerator.c', line 1891

static VALUE
lazy_reject(VALUE obj)
{
    if (!rb_block_given_p()) {
	rb_raise(rb_eArgError, "tried to call lazy reject without a block");
    }

    return lazy_add_method(obj, 0, 0, Qnil, Qnil, &lazy_reject_funcs);
}

#select Also known as: #find_all

[ GitHub ]

  
# File 'enumerator.c', line 1869

static VALUE
lazy_select(VALUE obj)
{
    if (!rb_block_given_p()) {
	rb_raise(rb_eArgError, "tried to call lazy select without a block");
    }

    return lazy_add_method(obj, 0, 0, Qnil, Qnil, &lazy_select_funcs);
}

#slice_after(*args)

Alias for #chunk.

#slice_before(*args)

Alias for #chunk.

#slice_when(*args)

Alias for #chunk.

#take(n)

[ GitHub ]

  
# File 'enumerator.c', line 2106

static VALUE
lazy_take(VALUE obj, VALUE n)
{
    long len = NUM2LONG(n);
    int argc = 0;
    VALUE argv[2];

    if (len < 0) {
	rb_raise(rb_eArgError, "attempt to take negative size");
    }

    if (len == 0) {
       argv[0] = sym_cycle;
       argv[1] = INT2NUM(0);
       argc = 2;
    }

    return lazy_add_method(obj, argc, argv, n, rb_ary_new3(1, n), &lazy_take_funcs);
}

#take_while

[ GitHub ]

  
# File 'enumerator.c', line 2141

static VALUE
lazy_take_while(VALUE obj)
{
    if (!rb_block_given_p()) {
	rb_raise(rb_eArgError, "tried to call lazy take_while without a block");
    }

    return lazy_add_method(obj, 0, 0, Qnil, Qnil, &lazy_take_while_funcs);
}

#to_enum(method = :each, *args) ⇒ Lazy #enum_for(method = :each, *args) ⇒ Lazy #to_enum(method = :each, *args) {|*args| ... } ⇒ Lazy #enum_for(method = :each, *args) {|*args| ... } ⇒ Lazy
Also known as: #enum_for

Similar to Object#to_enum, except it returns a lazy enumerator. This makes it easy to define ::Enumerable methods that will naturally remain lazy if called from a lazy enumerator.

For example, continuing from the example in Object#to_enum:

# See Kernel#to_enum for the definition of repeat
r = 1..Float::INFINITY
r.repeat(2).first(5) # => [1, 1, 2, 2, 3]
r.repeat(2).class # => Enumerator
r.repeat(2).map{|n| n ** 2}.first(5) # => endless loop!
# works naturally on lazy enumerator:
r.lazy.repeat(2).class # => Enumerator::Lazy
r.lazy.repeat(2).map{|n| n ** 2}.first(5) # => [1, 1, 4, 4, 9]
[ GitHub ]

  
# File 'enumerator.c', line 1706

static VALUE
lazy_to_enum(int argc, VALUE *argv, VALUE self)
{
    VALUE lazy, meth = sym_each;

    if (argc > 0) {
	--argc;
	meth = *argv++;
    }
    lazy = lazy_to_enum_i(self, meth, argc, argv, 0);
    if (rb_block_given_p()) {
	enumerator_ptr(lazy)->size = rb_block_proc();
    }
    return lazy;
}

#uniq

[ GitHub ]

  
# File 'enumerator.c', line 2267

static VALUE
lazy_uniq(VALUE obj)
{
    rb_block_call_func *const func =
	rb_block_given_p() ? lazy_uniq_iter : lazy_uniq_func;
    return lazy_set_method(rb_block_call(rb_cLazy, id_new, 1, &obj,
					 func, 0),
			   0, 0);
}

#zip(*args)

[ GitHub ]

  
# File 'enumerator.c', line 2038

static VALUE
lazy_zip(int argc, VALUE *argv, VALUE obj)
{
    VALUE ary, v;
    long i;
    rb_block_call_func *func = lazy_zip_arrays_func;

    if (rb_block_given_p()) {
	return rb_call_super(argc, argv);
    }

    ary = rb_ary_new2(argc);
    for (i = 0; i < argc; i++) {
	v = rb_check_array_type(argv[i]);
	if (NIL_P(v)) {
	    for (; i < argc; i++) {
		if (!rb_respond_to(argv[i], id_each)) {
		    rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (must respond to :each)",
			     rb_obj_class(argv[i]));
		}
	    }
	    ary = rb_ary_new4(argc, argv);
	    func = lazy_zip_func;
	    break;
	}
	rb_ary_push(ary, v);
    }

    return lazy_set_method(rb_block_call(rb_cLazy, id_new, 1, &obj,
					 func, ary),
			   ary, lazy_receiver_size);
}