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
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)
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
|
# File 'enumerator.c', line 1305
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
1844
1845
1846
1847
1848
|
# File 'enumerator.c', line 1844
static VALUE
lazy_super(int argc, VALUE *argv, VALUE lazy)
{
return enumerable_lazy(rb_call_super(argc, argv));
}
|
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
|
# File 'enumerator.c', line 1439
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);
}
|
#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
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
|
# File 'enumerator.c', line 1523
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);
}
|
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
|
# File 'enumerator.c', line 1807
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
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
|
# File 'enumerator.c', line 1833
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)
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
|
# File 'enumerator.c', line 1414
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;
}
|
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
|
# File 'enumerator.c', line 1546
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);
}
|
#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
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
|
# File 'enumerator.c', line 1523
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);
}
|
1605
1606
1607
1608
1609
1610
1611
1612
1613
|
# File 'enumerator.c', line 1605
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);
}
|
1850
1851
1852
1853
1854
|
# File 'enumerator.c', line 1850
static VALUE
lazy_lazy(VALUE obj)
{
return obj;
}
|
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
|
# File 'enumerator.c', line 1439
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);
}
|
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
|
# File 'enumerator.c', line 1569
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);
}
|
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
|
# File 'enumerator.c', line 1546
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
1844
1845
1846
1847
1848
|
# File 'enumerator.c', line 1844
static VALUE
lazy_super(int argc, VALUE *argv, VALUE lazy)
{
return enumerable_lazy(rb_call_super(argc, argv));
}
|
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
|
# File 'enumerator.c', line 1736
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 = INT2NUM(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
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
|
# File 'enumerator.c', line 1765
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)
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
|
# File 'enumerator.c', line 1414
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;
}
|
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
|
# File 'enumerator.c', line 1674
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);
}
|