[前][次][番号順一覧][スレッド一覧]

ruby-changes:56179

From: Shugo <ko1@a...>
Date: Fri, 21 Jun 2019 17:43:22 +0900 (JST)
Subject: [ruby-changes:56179] Shugo Maeda: 702cf3ec90 (trunk): Enumerator::Lazy should support filter_map

https://git.ruby-lang.org/ruby.git/commit/?id=702cf3ec90

From 702cf3ec9051914c8ef5a353580e0e74f7ec7005 Mon Sep 17 00:00:00 2001
From: Shugo Maeda <shugo@r...>
Date: Fri, 21 Jun 2019 17:27:20 +0900
Subject: Enumerator::Lazy should support filter_map

Fixes [Bug #15949]

diff --git a/enumerator.c b/enumerator.c
index c37c8af..3fb953c 100644
--- a/enumerator.c
+++ b/enumerator.c
@@ -2060,6 +2060,37 @@ lazy_filter_map(VALUE obj) https://github.com/ruby/ruby/blob/trunk/enumerator.c#L2060
 }
 
 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)
 {
     VALUE chain = lazyenum_yield(proc_entry, result);
diff --git a/test/ruby/test_lazy_enumerator.rb b/test/ruby/test_lazy_enumerator.rb
index e76a53e..679e029 100644
--- a/test/ruby/test_lazy_enumerator.rb
+++ b/test/ruby/test_lazy_enumerator.rb
@@ -116,6 +116,14 @@ class TestLazyEnumerator < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_lazy_enumerator.rb#L116
     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)
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]