1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Enumerator::Lazy should support filter_map

Fixes [Bug #15949]
This commit is contained in:
Shugo Maeda 2019-06-21 17:27:20 +09:00
parent 35392ff0a0
commit 702cf3ec90
No known key found for this signature in database
GPG key ID: 568AD8CEAD744A13
2 changed files with 39 additions and 0 deletions

View file

@ -2059,6 +2059,37 @@ lazy_filter_map(VALUE obj)
Qnil, 0);
}
static struct MEMO *
lazy_filter_map_proc(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index)
{
VALUE value = lazyenum_yield_values(proc_entry, result);
if (!RTEST(value)) return 0;
LAZY_MEMO_SET_VALUE(result, value);
LAZY_MEMO_RESET_PACKED(result);
return result;
}
static const lazyenum_funcs lazy_filter_map_funcs = {
lazy_filter_map_proc, 0,
};
/*
* call-seq:
* lazy.filter_map { |obj| block } -> lazy_enumerator
*
* Like Enumerable#filter_map, but chains operation to be lazy-evaluated.
*/
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);
}
static struct MEMO *
lazy_reject_proc(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index)
{

View file

@ -116,6 +116,14 @@ class TestLazyEnumerator < Test::Unit::TestCase
assert_equal(expected, a.lazy.map {|*args| args}.map {|*args| args}.to_a, bug)
end
def test_filter_map
a = Step.new(1..3)
assert_equal(2, a.filter_map {|x| x.odd? && x * 2}.first)
assert_equal(3, a.current)
assert_equal(2, a.lazy.filter_map {|x| x.odd? && x * 2}.first)
assert_equal(1, a.current)
end
def test_flat_map
a = Step.new(1..3)
assert_equal(2, a.flat_map {|x| [x * 2]}.first)