Movatterモバイル変換


[0]ホーム

URL:


HomeClassesMethods

In Files

  • enumerator.c

Parent

Enumerator

Methods

Files

Class/Module Index[+]

Quicksearch
No matching classes.

Enumerator::Lazy

Enumerator::Lazy is a special type ofEnumerator, that allows constructing chainsof operations without evaluating them immediately, and evaluating values onas-needed basis. In order to do so it redefines most ofEnumerable methods so that they justconstruct another lazy enumerator.

Enumerator::Lazy can be constructed from anyEnumerable with theEnumerable#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-redefinedEnumerable method is called, likeEnumerable#first orEnumerable#to_a (the latter isaliased asforce for more semanticcode):

lazy.first(2)#=> [21, 23]lazy.force#=> [21, 23, 25, 27, 29]

Note that mostEnumerable methods thatcould be called with or without a block, onEnumerator::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, aswell 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 dataURLS.map {|u|JSON.parse(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 conditionURLS.lazy.map {|u|JSON.parse(open(u).read) }  .select {|data|data.key?('stats') }  .first(5)

Ending a chain with “.eager” generates a non-lazy enumerator, which issuitable for returning or passing to another method that expects a normalenumerator.

defactive_itemsgroups    .lazy    .flat_map(&:items)    .reject(&:disabled)    .eagerend# 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)

Public Class Methods

new(obj, size=nil) { |yielder, *values| block }click to toggle source

Creates a newLazy enumerator. When the enumeratoris actually enumerated (e.g. by callingforce),obj will beenumerated and each value passed to the given block. The block can yieldvalues back usingyielder. For example, to create a“filter+map” enumerator:

deffilter_map(sequence)Lazy.new(sequence)do|yielder,*values|result =yield*valuesyielder<<resultifresultendendfilter_map(1..Float::INFINITY) {|i|i*iifi.even?}.first(5)#=> [4, 16, 36, 64, 100]
                static VALUElazy_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;}

Public Instance Methods

_enumerable_collect()click to toggle source
Alias for:collect
_enumerable_collect_concat()click to toggle source
Alias for:collect_concat
_enumerable_drop(p1)click to toggle source
Alias for:drop
_enumerable_drop_while()click to toggle source
Alias for:drop_while
_enumerable_filter()click to toggle source
Alias for:filter
_enumerable_filter_map()click to toggle source
Alias for:filter_map
_enumerable_find_all()click to toggle source
Alias for:find_all
_enumerable_flat_map()click to toggle source
Alias for:flat_map
_enumerable_grep(p1)click to toggle source
Alias for:grep
_enumerable_grep_v(p1)click to toggle source
Alias for:grep_v
_enumerable_map()click to toggle source
Alias for:map
_enumerable_reject()click to toggle source
Alias for:reject
_enumerable_select()click to toggle source
Alias for:select
_enumerable_take(p1)click to toggle source
Alias for:take
_enumerable_take_while()click to toggle source
Alias for:take_while
_enumerable_uniq()click to toggle source
Alias for:uniq
_enumerable_zip(*args)click to toggle source
Alias for:zip
chunk(*args)click to toggle source

LikeEnumerable#chunk, butchains operation to be lazy-evaluated.

                static VALUElazy_super(int argc, VALUE *argv, VALUE lazy){    return enumerable_lazy(rb_call_super(argc, argv));}
chunk_while(*args)click to toggle source

LikeEnumerable#chunk_while,but chains operation to be lazy-evaluated.

                static VALUElazy_super(int argc, VALUE *argv, VALUE lazy){    return enumerable_lazy(rb_call_super(argc, argv));}
collect { |obj| block } → lazy_enumeratorclick to toggle source

LikeEnumerable#map, butchains operation to be lazy-evaluated.

(1..Float::INFINITY).lazy.map {|i|i**2 }#=> #<Enumerator::Lazy: #<Enumerator::Lazy: 1..Infinity>:map>(1..Float::INFINITY).lazy.map {|i|i**2 }.first(3)#=> [1, 4, 9]
                static VALUElazy_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);}
Also aliased as:_enumerable_collect
collect_concat { |obj| block } → a_lazy_enumeratorclick to toggle source

Returns a new lazy enumerator with the concatenated results of runningblock 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 valuex returned byblock is decomposed ifeither of the following conditions is true:

  • x responds to both each and force, which means thatx is a lazy enumerator.

  • x 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}]
                static VALUElazy_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);}
drop(n) → lazy_enumeratorclick to toggle source

LikeEnumerable#drop, butchains operation to be lazy-evaluated.

                static VALUElazy_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);}
Also aliased as:_enumerable_drop
drop_while { |obj| block } → lazy_enumeratorclick to toggle source

LikeEnumerable#drop_while,but chains operation to be lazy-evaluated.

                static VALUElazy_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);}
Also aliased as:_enumerable_drop_while
eager → enumclick to toggle source

Returns a non-lazyEnumerator convertedfrom the lazy enumerator.

                static VALUElazy_eager(VALUE self){    return enumerator_init(enumerator_allocate(rb_cEnumerator),                           self, sym_each, 0, 0, lazy_eager_size, Qnil, 0);}
enum_for(method = :each, *args) → lazy_enumclick to toggle source
enum_for(method = :each, *args) {|*args| block } → lazy_enum

Similar toObject#to_enum,except it returns a lazy enumerator. This makes it easy to defineEnumerable methods that will naturally remainlazy if called from a lazy enumerator.

For example, continuing from the example inObject#to_enum:

# See Object#to_enum for the definition of repeatr =1..Float::INFINITYr.repeat(2).first(5)# => [1, 1, 2, 2, 3]r.repeat(2).class# => Enumeratorr.repeat(2).map{|n|n**2}.first(5)# => endless loop!# works naturally on lazy enumerator:r.lazy.repeat(2).class# => Enumerator::Lazyr.lazy.repeat(2).map{|n|n**2}.first(5)# => [1, 1, 4, 4, 9]
                static VALUElazy_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()) {        enumerator_ptr(lazy)->size = rb_block_proc();    }    return lazy;}
filter { |obj| block } → lazy_enumeratorclick to toggle source

LikeEnumerable#select,but chains operation to be lazy-evaluated.

                static VALUElazy_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);}
Also aliased as:_enumerable_filter
filter_map { |obj| block } → lazy_enumeratorclick to toggle source

LikeEnumerable#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]
                static VALUElazy_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);}
Also aliased as:_enumerable_filter_map
find_all { |obj| block } → lazy_enumeratorclick to toggle source

LikeEnumerable#select,but chains operation to be lazy-evaluated.

                static VALUElazy_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);}
Also aliased as:_enumerable_find_all
flat_map { |obj| block } → a_lazy_enumeratorclick to toggle source

Returns a new lazy enumerator with the concatenated results of runningblock 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 valuex returned byblock is decomposed ifeither of the following conditions is true:

  • x responds to both each and force, which means thatx is a lazy enumerator.

  • x 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}]
                static VALUElazy_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);}
Also aliased as:_enumerable_flat_map
force()click to toggle source
Alias for:to_a
grep(pattern) → lazy_enumeratorclick to toggle source
grep(pattern) { |obj| block } → lazy_enumerator

LikeEnumerable#grep, butchains operation to be lazy-evaluated.

                static VALUElazy_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);}
Also aliased as:_enumerable_grep
grep_v(pattern) → lazy_enumeratorclick to toggle source
grep_v(pattern) { |obj| block } → lazy_enumerator

LikeEnumerable#grep_v,but chains operation to be lazy-evaluated.

                static VALUElazy_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);}
Also aliased as:_enumerable_grep_v
lazy → lazy_enumeratorclick to toggle source

Returns self.

                static VALUElazy_lazy(VALUE obj){    return obj;}
map { |obj| block } → lazy_enumeratorclick to toggle source

LikeEnumerable#map, butchains operation to be lazy-evaluated.

(1..Float::INFINITY).lazy.map {|i|i**2 }#=> #<Enumerator::Lazy: #<Enumerator::Lazy: 1..Infinity>:map>(1..Float::INFINITY).lazy.map {|i|i**2 }.first(3)#=> [1, 4, 9]
                static VALUElazy_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);}
Also aliased as:_enumerable_map
reject { |obj| block } → lazy_enumeratorclick to toggle source

LikeEnumerable#reject,but chains operation to be lazy-evaluated.

                static VALUElazy_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);}
Also aliased as:_enumerable_reject
select { |obj| block } → lazy_enumeratorclick to toggle source

LikeEnumerable#select,but chains operation to be lazy-evaluated.

                static VALUElazy_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);}
Also aliased as:_enumerable_select
slice_after(*args)click to toggle source

LikeEnumerable#slice_after,but chains operation to be lazy-evaluated.

                static VALUElazy_super(int argc, VALUE *argv, VALUE lazy){    return enumerable_lazy(rb_call_super(argc, argv));}
slice_before(*args)click to toggle source

LikeEnumerable#slice_before,but chains operation to be lazy-evaluated.

                static VALUElazy_super(int argc, VALUE *argv, VALUE lazy){    return enumerable_lazy(rb_call_super(argc, argv));}
slice_when(*args)click to toggle source

LikeEnumerable#slice_when,but chains operation to be lazy-evaluated.

                static VALUElazy_super(int argc, VALUE *argv, VALUE lazy){    return enumerable_lazy(rb_call_super(argc, argv));}
take(n) → lazy_enumeratorclick to toggle source

LikeEnumerable#take, butchains operation to be lazy-evaluated.

                static VALUElazy_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);}
Also aliased as:_enumerable_take
take_while { |obj| block } → lazy_enumeratorclick to toggle source

LikeEnumerable#take_while,but chains operation to be lazy-evaluated.

                static VALUElazy_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);}
Also aliased as:_enumerable_take_while
to_a → arrayclick to toggle source
force → array

Expandslazy enumerator to an array. SeeEnumerable#to_a.

                static VALUE lazy_to_a(VALUE self){}
Also aliased as:force
to_enum(method = :each, *args) → lazy_enumclick to toggle source
to_enum(method = :each, *args) {|*args| block } → lazy_enum

Similar toObject#to_enum,except it returns a lazy enumerator. This makes it easy to defineEnumerable methods that will naturally remainlazy if called from a lazy enumerator.

For example, continuing from the example inObject#to_enum:

# See Object#to_enum for the definition of repeatr =1..Float::INFINITYr.repeat(2).first(5)# => [1, 1, 2, 2, 3]r.repeat(2).class# => Enumeratorr.repeat(2).map{|n|n**2}.first(5)# => endless loop!# works naturally on lazy enumerator:r.lazy.repeat(2).class# => Enumerator::Lazyr.lazy.repeat(2).map{|n|n**2}.first(5)# => [1, 1, 4, 4, 9]
                static VALUElazy_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()) {        enumerator_ptr(lazy)->size = rb_block_proc();    }    return lazy;}
uniq → lazy_enumeratorclick to toggle source
uniq { |item| block } → lazy_enumerator

LikeEnumerable#uniq, butchains operation to be lazy-evaluated.

                static VALUElazy_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);}
Also aliased as:_enumerable_uniq
with_index(offset = 0) {|(*args), idx| block }click to toggle source
with_index(offset = 0)

If a block is given, iterates the given block for each element with anindex, which starts fromoffset, and returns a lazy enumeratorthat yields the same values (without the index).

If a block is not given, returns a new lazy enumerator that includes theindex, starting fromoffset.

offset

the starting index to use

SeeEnumerator#with_index.

                static VALUElazy_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, ...) → lazy_enumeratorclick to toggle source
zip(arg, ...) { |arr| block } → nil

LikeEnumerable#zip, butchains operation to be lazy-evaluated. However, if a block is given to zip,values are enumerated immediately.

                static VALUElazy_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);}
Also aliased as:_enumerable_zip

Private Instance Methods

with_index(offset = 0) {|(*args), idx| ... }click to toggle source
with_index(offset = 0)

Iterates the given block for each element with an index, which starts fromoffset. If no block is given, returns a newEnumerator that includes the index, startingfromoffset

offset

the starting index to use

                static VALUEenumerator_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));}

This page was generated for Ruby 3.0.0

Generated with Ruby-doc Rdoc Generator 0.42.0.


[8]ページ先頭

©2009-2025 Movatter.jp