From 82b56a2825dc9d4facb6d1d0d8cb659feccd6209 Mon Sep 17 00:00:00 2001 From: Red Date: Tue, 17 Mar 2026 17:32:45 +0900 Subject: [ruby-core:122847] Implements `Enumerator::Lazy#tee` --- enumerator.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'enumerator.c') 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")); -- cgit v1.2.3