Class: Enumerator::Lazy
- Inherits:
- 
      Enumerator
      
        - Object
- Enumerator
- Enumerator::Lazy
 
- Defined in:
- enumerator.c,
 enumerator.c
Overview
Enumerator::Lazy is a special type of Enumerator, that allows constructing chains of operations without evaluating them immediately, and evaluating values on as-needed basis. In order to do so it redefines most of Enumerable methods so that they just construct another lazy enumerator.
Enumerator::Lazy can be constructed from any Enumerable with the Enumerable#lazy method.
lazy = (1..Float::INFINITY).lazy.select(&:odd?).drop(10).take_while { |i| i < 30 }
# => #<Enumerator::Lazy: #<Enumerator::Lazy: #<Enumerator::Lazy: #<Enumerator::Lazy: 1..Infinity>:select>:drop(10)>:take_while>
The real enumeration is performed when any non-redefined Enumerable method is called, like Enumerable#first or Enumerable#to_a (the latter is aliased as #force for more semantic code):
lazy.first(2)
#=> [21, 23]
lazy.force
#=> [21, 23, 25, 27, 29]
Note that most Enumerable methods that could be called with or without a block, on Enumerator::Lazy will always require a block:
[1, 2, 3].map       #=> #<Enumerator: [1, 2, 3]:map>
[1, 2, 3].lazy.map  # ArgumentError: tried to call lazy map without a block
This class allows idiomatic calculations on long or infinite sequences, as well as chaining of calculations without constructing intermediate arrays.
Example for working with a slowly calculated sequence:
require 'open-uri'
# This will fetch all URLs before selecting
# necessary data
URLS.map { |u| JSON.parse(URI.open(u).read) }
  .select { |data| data.key?('stats') }
  .first(5)
# This will fetch URLs one-by-one, only till
# there is enough data to satisfy the condition
URLS.lazy.map { |u| JSON.parse(URI.open(u).read) }
  .select { |data| data.key?('stats') }
  .first(5)
Ending a chain with “.eager” generates a non-lazy enumerator, which is suitable for returning or passing to another method that expects a normal enumerator.
def active_items
  groups
    .lazy
    .flat_map(&:items)
    .reject(&:disabled)
    .eager
end
# This works lazily; if a checked item is found, it stops
# iteration and does not look into remaining groups.
first_checked = active_items.find(&:checked)
# This returns an array of items like a normal enumerator does.
all_checked = active_items.select(&:checked)
Instance Method Summary collapse
- 
  
    
      #_enumerable_with_index(*args)  ⇒ Object 
    
    
  
  
  
  
  private
  
  
  
  
    Iterates the given block for each element with an index, which starts from offset.
- 
  
    
      #chunk {|elt| ... } ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    Like Enumerable#chunk, but chains operation to be lazy-evaluated. 
- 
  
    
      #chunk_while {|elt_before, elt_after| ... } ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    Like Enumerable#chunk_while, but chains operation to be lazy-evaluated. 
- 
  
    
      #collect  ⇒ Object 
    
    
      (also: #_enumerable_collect)
    
  
  
  
  
  
  
  
  
  
    Like Enumerable#map, but chains operation to be lazy-evaluated. 
- 
  
    
      #collect_concat  ⇒ Object 
    
    
      (also: #_enumerable_collect_concat)
    
  
  
  
  
  
  
  
  
  
    Returns a new lazy enumerator with the concatenated results of running blockonce for every element in the lazy enumerator.
- 
  
    
      #compact  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    Like Enumerable#compact, but chains operation to be lazy-evaluated. 
- 
  
    
      #drop(n)  ⇒ Object 
    
    
      (also: #_enumerable_drop)
    
  
  
  
  
  
  
  
  
  
    Like Enumerable#drop, but chains operation to be lazy-evaluated. 
- 
  
    
      #drop_while {|obj| ... } ⇒ Object 
    
    
      (also: #_enumerable_drop_while)
    
  
  
  
  
  
  
  
  
  
    Like Enumerable#drop_while, but chains operation to be lazy-evaluated. 
- 
  
    
      #eager  ⇒ Enumerator 
    
    
  
  
  
  
  
  
  
  
  
    Returns a non-lazy Enumerator converted from the lazy enumerator. 
- 
  
    
      #enum_for(*args)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    Similar to Object#to_enum, except it returns a lazy enumerator. 
- 
  
    
      #filter  ⇒ Object 
    
    
      (also: #_enumerable_filter)
    
  
  
  
  
  
  
  
  
  
    Like Enumerable#select, but chains operation to be lazy-evaluated. 
- 
  
    
      #filter_map {|obj| ... } ⇒ Object 
    
    
      (also: #_enumerable_filter_map)
    
  
  
  
  
  
  
  
  
  
    Like Enumerable#filter_map, but chains operation to be lazy-evaluated. 
- 
  
    
      #find_all  ⇒ Object 
    
    
      (also: #_enumerable_find_all)
    
  
  
  
  
  
  
  
  
  
    Like Enumerable#select, but chains operation to be lazy-evaluated. 
- 
  
    
      #flat_map  ⇒ Object 
    
    
      (also: #_enumerable_flat_map)
    
  
  
  
  
  
  
  
  
  
    Returns a new lazy enumerator with the concatenated results of running blockonce for every element in the lazy enumerator.
- 
  
    
      #grep(pattern)  ⇒ Object 
    
    
      (also: #_enumerable_grep)
    
  
  
  
  
  
  
  
  
  
    Like Enumerable#grep, but chains operation to be lazy-evaluated. 
- 
  
    
      #grep_v(pattern)  ⇒ Object 
    
    
      (also: #_enumerable_grep_v)
    
  
  
  
  
  
  
  
  
  
    Like Enumerable#grep_v, but chains operation to be lazy-evaluated. 
- 
  
    
      #new(obj, size = nil) {|yielder, *values| ... } ⇒ Object 
    
    
  
  
  
    constructor
  
  
  
  
  
  
  
    Creates a new Lazy enumerator. 
- 
  
    
      #lazy  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    Returns self. 
- 
  
    
      #map  ⇒ Object 
    
    
      (also: #_enumerable_map)
    
  
  
  
  
  
  
  
  
  
    Like Enumerable#map, but chains operation to be lazy-evaluated. 
- 
  
    
      #reject {|obj| ... } ⇒ Object 
    
    
      (also: #_enumerable_reject)
    
  
  
  
  
  
  
  
  
  
    Like Enumerable#reject, but chains operation to be lazy-evaluated. 
- 
  
    
      #select  ⇒ Object 
    
    
      (also: #_enumerable_select)
    
  
  
  
  
  
  
  
  
  
    Like Enumerable#select, but chains operation to be lazy-evaluated. 
- 
  
    
      #slice_after  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    Like Enumerable#slice_after, but chains operation to be lazy-evaluated. 
- 
  
    
      #slice_before  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    Like Enumerable#slice_before, but chains operation to be lazy-evaluated. 
- 
  
    
      #slice_when {|elt_before, elt_after| ... } ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    Like Enumerable#slice_when, but chains operation to be lazy-evaluated. 
- 
  
    
      #take(n)  ⇒ Object 
    
    
      (also: #_enumerable_take)
    
  
  
  
  
  
  
  
  
  
    Like Enumerable#take, but chains operation to be lazy-evaluated. 
- 
  
    
      #take_while {|obj| ... } ⇒ Object 
    
    
      (also: #_enumerable_take_while)
    
  
  
  
  
  
  
  
  
  
    Like Enumerable#take_while, but chains operation to be lazy-evaluated. 
- 
  
    
      #to_a  ⇒ Object 
    
    
      (also: #force)
    
  
  
  
  
  
  
  
  
  
    Expands lazyenumerator to an array.
- 
  
    
      #to_enum(*args)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    Similar to Object#to_enum, except it returns a lazy enumerator. 
- 
  
    
      #uniq  ⇒ Object 
    
    
      (also: #_enumerable_uniq)
    
  
  
  
  
  
  
  
  
  
    Like Enumerable#uniq, but chains operation to be lazy-evaluated. 
- 
  
    
      #with_index(*args)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    If a block is given, returns a lazy enumerator that will iterate over the given block for each element with an index, which starts from offset, and returns a lazy enumerator that yields the same values (without the index).
- 
  
    
      #zip(*args)  ⇒ Object 
    
    
      (also: #_enumerable_zip)
    
  
  
  
  
  
  
  
  
  
    Like Enumerable#zip, but chains operation to be lazy-evaluated. 
Methods inherited from Enumerator
#+, #each, #each_with_index, #each_with_object, #feed, #initialize_copy, #inspect, #next, #next_values, #peek, #peek_values, produce, product, #rewind, #size, #with_object
Methods included from Enumerable
#all?, #any?, #chain, #count, #cycle, #detect, #each_cons, #each_entry, #each_slice, #each_with_index, #each_with_object, #entries, #find, #find_index, #first, #group_by, #include?, #inject, #max, #max_by, #member?, #min, #min_by, #minmax, #minmax_by, #none?, #one?, #partition, #reduce, #reverse_each, #sort, #sort_by, #sum, #tally, #to_h
Constructor Details
#new(obj, size = nil) {|yielder, *values| ... } ⇒ Object
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 “filter+map” enumerator:
def filter_map(sequence)
  Lazy.new(sequence) do |yielder, *values|
    result = yield *values
    yielder << result if result
  end
end
filter_map(1..Float::INFINITY) {|i| i*i if i.even?}.first(5)
#=> [4, 16, 36, 64, 100]
| 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 | # File 'enumerator.c', line 1802
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, 0);
    rb_ivar_set(self, id_receiver, obj);
    return self;
} | 
Instance Method Details
#with_index(offset = 0) {|(*args), idx| ... } ⇒ Object (private) #with_index(offset = 0) ⇒ Object (private)
Iterates the given block for each element with an index, which starts from offset.  If no block is given, returns a new Enumerator that includes the index, starting from offset
- offset
- 
the starting index to use 
| 674 675 676 677 678 679 680 681 682 683 | # File 'enumerator.c', line 674
static VALUE
enumerator_with_index(int argc, VALUE *argv, VALUE obj)
{
    VALUE memo;
    rb_check_arity(argc, 0, 1);
    RETURN_SIZED_ENUMERATOR(obj, argc, argv, enumerator_enum_size);
    memo = (!argc || NIL_P(memo = argv[0])) ? INT2FIX(0) : rb_to_int(memo);
    return enumerator_block_call(obj, enumerator_with_index_i, (VALUE)MEMO_NEW(memo, 0, 0));
} | 
#chunk {|elt| ... } ⇒ Object
Like Enumerable#chunk, but chains operation to be lazy-evaluated.
| 2839 2840 2841 2842 2843 | # File 'enumerator.c', line 2839
static VALUE
lazy_super(int argc, VALUE *argv, VALUE lazy)
{
    return enumerable_lazy(rb_call_super(argc, argv));
} | 
#chunk_while {|elt_before, elt_after| ... } ⇒ Object
Like Enumerable#chunk_while, but chains operation to be lazy-evaluated.
| 2839 2840 2841 2842 2843 | # File 'enumerator.c', line 2839
static VALUE
lazy_super(int argc, VALUE *argv, VALUE lazy)
{
    return enumerable_lazy(rb_call_super(argc, argv));
} | 
#collect {|obj| ... } ⇒ Object #map {|obj| ... } ⇒ Object Also known as: _enumerable_collect
| 2066 2067 2068 2069 2070 2071 2072 2073 2074 | # File 'enumerator.c', line 2066
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);
} | 
#collect_concat {|obj| ... } ⇒ Object #flat_map {|obj| ... } ⇒ Object Also known as: _enumerable_collect_concat
Returns a new lazy enumerator with the concatenated results of running block once for every element in the lazy enumerator.
["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:
- 
xresponds to both each and force, which means thatxis a lazy enumerator.
- 
xis 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}]
| 2151 2152 2153 2154 2155 2156 2157 2158 2159 | # File 'enumerator.c', line 2151
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_add_method(obj, 0, 0, Qnil, Qnil, &lazy_flat_map_funcs);
} | 
#compact ⇒ Object
Like Enumerable#compact, but chains operation to be lazy-evaluated.
| 2709 2710 2711 2712 2713 | # File 'enumerator.c', line 2709
static VALUE
lazy_compact(VALUE obj)
{
    return lazy_add_method(obj, 0, 0, Qnil, Qnil, &lazy_compact_funcs);
} | 
#drop(n) ⇒ Object Also known as: _enumerable_drop
Like Enumerable#drop, but chains operation to be lazy-evaluated.
| 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 | # File 'enumerator.c', line 2584
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 {|obj| ... } ⇒ Object Also known as: _enumerable_drop_while
Like Enumerable#drop_while, but chains operation to be lazy-evaluated.
| 2628 2629 2630 2631 2632 2633 2634 2635 2636 | # File 'enumerator.c', line 2628
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);
} | 
#eager ⇒ Enumerator
Returns a non-lazy Enumerator converted from the lazy enumerator.
| 2006 2007 2008 2009 2010 2011 | # File 'enumerator.c', line 2006
static VALUE
lazy_eager(VALUE self)
{
    return enumerator_init(enumerator_allocate(rb_cEnumerator),
                           self, sym_each, 0, 0, lazy_eager_size, Qnil, 0);
} | 
#to_enum(method = :each, *args) ⇒ Object #enum_for(method = :each, *args) ⇒ Object #to_enum(method = :each, *args) {|*args| ... } ⇒ Object #enum_for(method = :each, *args) {|*args| ... } ⇒ Object
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 Object#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]
| 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 | # File 'enumerator.c', line 1974
static VALUE
lazy_to_enum(int argc, VALUE *argv, VALUE self)
{
    VALUE lazy, meth = sym_each, super_meth;
    if (argc > 0) {
        --argc;
        meth = *argv++;
    }
    if (RTEST((super_meth = rb_hash_aref(lazy_use_super_method, meth)))) {
        meth = super_meth;
    }
    lazy = lazy_to_enum_i(self, meth, argc, argv, 0, rb_keyword_given_p());
    if (rb_block_given_p()) {
        RB_OBJ_WRITE(lazy, &enumerator_ptr(lazy)->size, rb_block_proc());
    }
    return lazy;
} | 
#find_all {|obj| ... } ⇒ Object #select {|obj| ... } ⇒ Object #filter {|obj| ... } ⇒ Object Also known as: _enumerable_filter
Like Enumerable#select, but chains operation to be lazy-evaluated.
| 2181 2182 2183 2184 2185 2186 2187 2188 2189 | # File 'enumerator.c', line 2181
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);
} | 
#filter_map {|obj| ... } ⇒ Object Also known as: _enumerable_filter_map
Like Enumerable#filter_map, but chains operation to be lazy-evaluated.
(1..).lazy.filter_map { |i| i * 2 if i.even? }.first(5)
#=> [4, 8, 12, 16, 20]
| 2215 2216 2217 2218 2219 2220 2221 2222 2223 | # File 'enumerator.c', line 2215
static VALUE
lazy_filter_map(VALUE obj)
{
    if (!rb_block_given_p()) {
        rb_raise(rb_eArgError, "tried to call lazy filter_map without a block");
    }
    return lazy_add_method(obj, 0, 0, Qnil, Qnil, &lazy_filter_map_funcs);
} | 
#find_all {|obj| ... } ⇒ Object #select {|obj| ... } ⇒ Object #filter {|obj| ... } ⇒ Object Also known as: _enumerable_find_all
Like Enumerable#select, but chains operation to be lazy-evaluated.
| 2181 2182 2183 2184 2185 2186 2187 2188 2189 | # File 'enumerator.c', line 2181
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);
} | 
#collect_concat {|obj| ... } ⇒ Object #flat_map {|obj| ... } ⇒ Object Also known as: _enumerable_flat_map
Returns a new lazy enumerator with the concatenated results of running block once for every element in the lazy enumerator.
["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:
- 
xresponds to both each and force, which means thatxis a lazy enumerator.
- 
xis 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}]
| 2151 2152 2153 2154 2155 2156 2157 2158 2159 | # File 'enumerator.c', line 2151
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_add_method(obj, 0, 0, Qnil, Qnil, &lazy_flat_map_funcs);
} | 
#grep(pattern) ⇒ Object #grep(pattern) {|obj| ... } ⇒ Object Also known as: _enumerable_grep
Like Enumerable#grep, but chains operation to be lazy-evaluated.
| 2293 2294 2295 2296 2297 2298 2299 | # File 'enumerator.c', line 2293
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) ⇒ Object #grep_v(pattern) {|obj| ... } ⇒ Object Also known as: _enumerable_grep_v
Like Enumerable#grep_v, but chains operation to be lazy-evaluated.
| 2340 2341 2342 2343 2344 2345 2346 | # File 'enumerator.c', line 2340
static VALUE
lazy_grep_v(VALUE obj, VALUE pattern)
{
    const lazyenum_funcs *const funcs = rb_block_given_p() ?
        &lazy_grep_v_iter_funcs : &lazy_grep_v_funcs;
    return lazy_add_method(obj, 0, 0, pattern, rb_ary_new3(1, pattern), funcs);
} | 
#lazy ⇒ Object
Returns self.
| 2852 2853 2854 2855 2856 | # File 'enumerator.c', line 2852
static VALUE
lazy_lazy(VALUE obj)
{
    return obj;
} | 
#collect {|obj| ... } ⇒ Object #map {|obj| ... } ⇒ Object Also known as: _enumerable_map
| 2066 2067 2068 2069 2070 2071 2072 2073 2074 | # File 'enumerator.c', line 2066
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 {|obj| ... } ⇒ Object Also known as: _enumerable_reject
Like Enumerable#reject, but chains operation to be lazy-evaluated.
| 2244 2245 2246 2247 2248 2249 2250 2251 2252 | # File 'enumerator.c', line 2244
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);
} | 
#find_all {|obj| ... } ⇒ Object #select {|obj| ... } ⇒ Object #filter {|obj| ... } ⇒ Object Also known as: _enumerable_select
Like Enumerable#select, but chains operation to be lazy-evaluated.
| 2181 2182 2183 2184 2185 2186 2187 2188 2189 | # File 'enumerator.c', line 2181
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(pattern) ⇒ Object #slice_after {|elt| ... } ⇒ Object
Like Enumerable#slice_after, but chains operation to be lazy-evaluated.
| 2839 2840 2841 2842 2843 | # File 'enumerator.c', line 2839
static VALUE
lazy_super(int argc, VALUE *argv, VALUE lazy)
{
    return enumerable_lazy(rb_call_super(argc, argv));
} | 
#slice_before(pattern) ⇒ Object #slice_before {|elt| ... } ⇒ Object
Like Enumerable#slice_before, but chains operation to be lazy-evaluated.
| 2839 2840 2841 2842 2843 | # File 'enumerator.c', line 2839
static VALUE
lazy_super(int argc, VALUE *argv, VALUE lazy)
{
    return enumerable_lazy(rb_call_super(argc, argv));
} | 
#slice_when {|elt_before, elt_after| ... } ⇒ Object
Like Enumerable#slice_when, but chains operation to be lazy-evaluated.
| 2839 2840 2841 2842 2843 | # File 'enumerator.c', line 2839
static VALUE
lazy_super(int argc, VALUE *argv, VALUE lazy)
{
    return enumerable_lazy(rb_call_super(argc, argv));
} | 
#take(n) ⇒ Object Also known as: _enumerable_take
Like Enumerable#take, but chains operation to be lazy-evaluated.
| 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 | # File 'enumerator.c', line 2494
static VALUE
lazy_take(VALUE obj, VALUE n)
{
    long len = NUM2LONG(n);
    if (len < 0) {
        rb_raise(rb_eArgError, "attempt to take negative size");
    }
    n = LONG2NUM(len);          /* no more conversion */
    return lazy_add_method(obj, 0, 0, n, rb_ary_new3(1, n), &lazy_take_funcs);
} | 
#take_while {|obj| ... } ⇒ Object Also known as: _enumerable_take_while
Like Enumerable#take_while, but chains operation to be lazy-evaluated.
| 2530 2531 2532 2533 2534 2535 2536 2537 2538 | # File 'enumerator.c', line 2530
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_a ⇒ Array #force ⇒ Array Also known as: force
Expands lazy enumerator to an array. See Enumerable#to_a.
| 1833 1834 1835 1836 | # File 'enumerator.c', line 1833 static VALUE lazy_to_a(VALUE self) { } | 
#to_enum(method = :each, *args) ⇒ Object #enum_for(method = :each, *args) ⇒ Object #to_enum(method = :each, *args) {|*args| ... } ⇒ Object #enum_for(method = :each, *args) {|*args| ... } ⇒ Object
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 Object#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]
| 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 | # File 'enumerator.c', line 1974
static VALUE
lazy_to_enum(int argc, VALUE *argv, VALUE self)
{
    VALUE lazy, meth = sym_each, super_meth;
    if (argc > 0) {
        --argc;
        meth = *argv++;
    }
    if (RTEST((super_meth = rb_hash_aref(lazy_use_super_method, meth)))) {
        meth = super_meth;
    }
    lazy = lazy_to_enum_i(self, meth, argc, argv, 0, rb_keyword_given_p());
    if (rb_block_given_p()) {
        RB_OBJ_WRITE(lazy, &enumerator_ptr(lazy)->size, rb_block_proc());
    }
    return lazy;
} | 
#uniq ⇒ Object #uniq {|item| ... } ⇒ Object Also known as: _enumerable_uniq
Like Enumerable#uniq, but chains operation to be lazy-evaluated.
| 2683 2684 2685 2686 2687 2688 2689 | # File 'enumerator.c', line 2683
static VALUE
lazy_uniq(VALUE obj)
{
    const lazyenum_funcs *const funcs =
        rb_block_given_p() ? &lazy_uniq_iter_funcs : &lazy_uniq_funcs;
    return lazy_add_method(obj, 0, 0, Qnil, Qnil, funcs);
} | 
#with_index(offset = 0) {|(*args), idx| ... } ⇒ Object #with_index(offset = 0) ⇒ Object
If a block is given, returns a lazy enumerator that will iterate over the given block for each element with an index, which starts from offset, and returns a lazy enumerator that yields the same values (without the index).
If a block is not given, returns a new lazy enumerator that includes the index, starting from offset.
- offset
- 
the starting index to use 
See Enumerator#with_index.
| 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 | # File 'enumerator.c', line 2767
static VALUE
lazy_with_index(int argc, VALUE *argv, VALUE obj)
{
    VALUE memo;
    rb_scan_args(argc, argv, "01", &memo);
    if (NIL_P(memo))
        memo = LONG2NUM(0);
    return lazy_add_method(obj, 0, 0, memo, rb_ary_new_from_values(1, &memo), &lazy_with_index_funcs);
} | 
#zip(arg, ...) ⇒ Object #zip(arg, ...) {|arr| ... } ⇒ nil Also known as: _enumerable_zip
Like Enumerable#zip, but chains operation to be lazy-evaluated. However, if a block is given to zip, values are enumerated immediately.
| 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 | # File 'enumerator.c', line 2419
static VALUE
lazy_zip(int argc, VALUE *argv, VALUE obj)
{
    VALUE ary, v;
    long i;
    const lazyenum_funcs *funcs = &lazy_zip_funcs[1];
    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);
            funcs = &lazy_zip_funcs[0];
            break;
        }
        rb_ary_push(ary, v);
    }
    return lazy_add_method(obj, 0, 0, ary, ary, funcs);
} |