Class: Enumerator::Lazy
Instance Method Summary
collapse
Methods inherited from Enumerator
#each, #each_with_index, #each_with_object, #feed, #initialize_copy, #inspect, #next, #next_values, #peek, #peek_values, #rewind, #size, #with_index, #with_object
Methods included from Enumerable
#all?, #any?, #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, #to_a, #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 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)
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
|
# File 'enumerator.c', line 1381
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
1926
1927
1928
1929
1930
|
# File 'enumerator.c', line 1926
static VALUE
lazy_super(int argc, VALUE *argv, VALUE lazy)
{
return enumerable_lazy(rb_call_super(argc, argv));
}
|
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
|
# File 'enumerator.c', line 1515
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_set_method(rb_block_call(rb_cLazy, id_new, 1, &obj,
lazy_map_func, 0),
Qnil, lazy_receiver_size);
}
|
#collect_concat {|obj| ... } ⇒ Object
#flat_map {|obj| ... } ⇒ Object
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
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
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
|
# File 'enumerator.c', line 1600
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_func, 0),
Qnil, 0);
}
|
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
|
# File 'enumerator.c', line 1889
static VALUE
lazy_drop(VALUE obj, VALUE n)
{
long len = NUM2LONG(n);
if (len < 0) {
rb_raise(rb_eArgError, "attempt to drop negative size");
}
return lazy_set_method(rb_block_call(rb_cLazy, id_new, 1, &obj,
lazy_drop_func, n),
rb_ary_new3(1, n), lazy_drop_size);
}
|
#drop_while ⇒ Object
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
|
# File 'enumerator.c', line 1915
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_set_method(rb_block_call(rb_cLazy, id_new, 1, &obj,
lazy_drop_while_func, 0),
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 Kernel#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 Kernel#to_enum:
r = 1..Float::INFINITY
r.repeat(2).first(5) r.repeat(2).class r.repeat(2).map{|n| n ** 2}.first(5) r.lazy.repeat(2).class r.lazy.repeat(2).map{|n| n ** 2}.first(5)
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
|
# File 'enumerator.c', line 1490
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;
}
|
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
|
# File 'enumerator.c', line 1623
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_set_method(rb_block_call(rb_cLazy, id_new, 1, &obj,
lazy_select_func, 0),
Qnil, 0);
}
|
#collect_concat {|obj| ... } ⇒ Object
#flat_map {|obj| ... } ⇒ Object
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
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
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
|
# File 'enumerator.c', line 1600
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_func, 0),
Qnil, 0);
}
|
1682
1683
1684
1685
1686
1687
1688
1689
1690
|
# File 'enumerator.c', line 1682
static VALUE
lazy_grep(VALUE obj, VALUE pattern)
{
return lazy_set_method(rb_block_call(rb_cLazy, id_new, 1, &obj,
rb_block_given_p() ?
lazy_grep_iter : lazy_grep_func,
pattern),
rb_ary_new3(1, pattern), 0);
}
|
1932
1933
1934
1935
1936
|
# File 'enumerator.c', line 1932
static VALUE
lazy_lazy(VALUE obj)
{
return obj;
}
|
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
|
# File 'enumerator.c', line 1515
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_set_method(rb_block_call(rb_cLazy, id_new, 1, &obj,
lazy_map_func, 0),
Qnil, lazy_receiver_size);
}
|
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
|
# File 'enumerator.c', line 1646
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_set_method(rb_block_call(rb_cLazy, id_new, 1, &obj,
lazy_reject_func, 0),
Qnil, 0);
}
|
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
|
# File 'enumerator.c', line 1623
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_set_method(rb_block_call(rb_cLazy, id_new, 1, &obj,
lazy_select_func, 0),
Qnil, 0);
}
|
#slice_before ⇒ Object
1926
1927
1928
1929
1930
|
# File 'enumerator.c', line 1926
static VALUE
lazy_super(int argc, VALUE *argv, VALUE lazy)
{
return enumerable_lazy(rb_call_super(argc, argv));
}
|
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
|
# File 'enumerator.c', line 1818
static VALUE
lazy_take(VALUE obj, VALUE n)
{
long len = NUM2LONG(n);
VALUE lazy;
if (len < 0) {
rb_raise(rb_eArgError, "attempt to take negative size");
}
if (len == 0) {
VALUE len = INT2FIX(0);
lazy = lazy_to_enum_i(obj, sym_cycle, 1, &len, 0);
}
else {
lazy = rb_block_call(rb_cLazy, id_new, 1, &obj,
lazy_take_func, n);
}
return lazy_set_method(lazy, rb_ary_new3(1, n), lazy_take_size);
}
|
#take_while ⇒ Object
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
|
# File 'enumerator.c', line 1847
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_set_method(rb_block_call(rb_cLazy, id_new, 1, &obj,
lazy_take_while_func, 0),
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 Kernel#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 Kernel#to_enum:
r = 1..Float::INFINITY
r.repeat(2).first(5) r.repeat(2).class r.repeat(2).map{|n| n ** 2}.first(5) r.lazy.repeat(2).class r.lazy.repeat(2).map{|n| n ** 2}.first(5)
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
|
# File 'enumerator.c', line 1490
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;
}
|
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
|
# File 'enumerator.c', line 1756
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 %s (must respond to :each)",
rb_obj_classname(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);
}
|