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)
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
|
# File 'enumerator.c', line 1383
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) ⇒ Object
1928
1929
1930
1931
1932
|
# File 'enumerator.c', line 1928
static VALUE
lazy_super(int argc, VALUE *argv, VALUE lazy)
{
return enumerable_lazy(rb_call_super(argc, argv));
}
|
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
|
# File 'enumerator.c', line 1517
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
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
|
# File 'enumerator.c', line 1602
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);
}
|
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
|
# File 'enumerator.c', line 1891
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
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
|
# File 'enumerator.c', line 1917
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)
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
|
# File 'enumerator.c', line 1492
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;
}
|
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
|
# File 'enumerator.c', line 1625
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
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
|
# File 'enumerator.c', line 1602
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);
}
|
#grep(pattern) ⇒ Object
1684
1685
1686
1687
1688
1689
1690
1691
1692
|
# File 'enumerator.c', line 1684
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);
}
|
1934
1935
1936
1937
1938
|
# File 'enumerator.c', line 1934
static VALUE
lazy_lazy(VALUE obj)
{
return obj;
}
|
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
|
# File 'enumerator.c', line 1517
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);
}
|
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
|
# File 'enumerator.c', line 1648
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);
}
|
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
|
# File 'enumerator.c', line 1625
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_after(*args) ⇒ Object
1928
1929
1930
1931
1932
|
# File 'enumerator.c', line 1928
static VALUE
lazy_super(int argc, VALUE *argv, VALUE lazy)
{
return enumerable_lazy(rb_call_super(argc, argv));
}
|
#slice_before(*args) ⇒ Object
1928
1929
1930
1931
1932
|
# File 'enumerator.c', line 1928
static VALUE
lazy_super(int argc, VALUE *argv, VALUE lazy)
{
return enumerable_lazy(rb_call_super(argc, argv));
}
|
#slice_when(*args) ⇒ Object
1928
1929
1930
1931
1932
|
# File 'enumerator.c', line 1928
static VALUE
lazy_super(int argc, VALUE *argv, VALUE lazy)
{
return enumerable_lazy(rb_call_super(argc, argv));
}
|
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
|
# File 'enumerator.c', line 1820
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
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
|
# File 'enumerator.c', line 1849
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)
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
|
# File 'enumerator.c', line 1492
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;
}
|
#zip(*args) ⇒ Object
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
1788
1789
|
# File 'enumerator.c', line 1758
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);
}
|