summaryrefslogtreecommitdiff
path: root/enumerator.c
diff options
context:
space:
mode:
authorRed <nuzer501@gmail.com>2026-03-17 17:32:45 +0900
committerGitHub <noreply@github.com>2026-03-17 17:32:45 +0900
commit82b56a2825dc9d4facb6d1d0d8cb659feccd6209 (patch)
treedf8b02beed61f2d96f55ac9a83677a09d246cb85 /enumerator.c
parenteb460a126b2bb54cd41aed8281e428b64969c315 (diff)
[ruby-core:122847] Implements `Enumerator::Lazy#tee`
Diffstat (limited to 'enumerator.c')
-rw-r--r--enumerator.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/enumerator.c b/enumerator.c
index b60036a3de..42c11a08f8 100644
--- a/enumerator.c
+++ b/enumerator.c
@@ -2771,6 +2771,52 @@ lazy_with_index(int argc, VALUE *argv, VALUE obj)
return lazy_add_method(obj, 0, 0, memo, rb_ary_new_from_values(1, &memo), &lazy_with_index_funcs);
}
+static struct MEMO *
+lazy_tee_proc(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index)
+{
+ struct proc_entry *entry = proc_entry_ptr(proc_entry);
+
+ rb_proc_call_with_block(entry->proc, 1, &result->memo_value, Qnil);
+
+ return result;
+}
+
+static const lazyenum_funcs lazy_tee_funcs = {
+ lazy_tee_proc, 0,
+};
+
+/*
+ * call-seq:
+ * lazy.tee { |item| ... } -> lazy_enumerator
+ *
+ * Passes each element through to the block for side effects only,
+ * without modifying the element or affecting the enumeration.
+ * Returns a new lazy enumerator.
+ *
+ * This is useful for debugging or logging inside lazy chains,
+ * without breaking laziness or misusing +map+.
+ *
+ * (1..).lazy
+ * .tee { |x| puts "got #{x}" }
+ * .select(&:even?)
+ * .first(3)
+ * # prints: got 1, got 2, ..., got 6
+ * # returns: [2, 4, 6]
+ *
+ * Similar in intent to Java's Stream#peek.
+ */
+
+static VALUE
+lazy_tee(VALUE obj)
+{
+ if (!rb_block_given_p())
+ {
+ rb_raise(rb_eArgError, "tried to call lazy tee without a block");
+ }
+
+ return lazy_add_method(obj, 0, 0, Qnil, Qnil, &lazy_tee_funcs);
+}
+
#if 0 /* for RDoc */
/*
@@ -4646,6 +4692,7 @@ InitVM_Enumerator(void)
rb_define_method(rb_cLazy, "uniq", lazy_uniq, 0);
rb_define_method(rb_cLazy, "compact", lazy_compact, 0);
rb_define_method(rb_cLazy, "with_index", lazy_with_index, -1);
+ rb_define_method(rb_cLazy, "tee", lazy_tee, 0);
lazy_use_super_method = rb_hash_new_with_size(18);
rb_hash_aset(lazy_use_super_method, sym("map"), sym("_enumerable_map"));