Skip to content

Commit 9242533

Browse files
transclaude
andcommitted
Add Kernel#tee, Tee alias, inline Array#remove, remove tap override
- Add Kernel#tee as block-less method chaining via Tee/Functor - Add Tee as alias for Functor (gradual rename) - Remove Kernel#tap override (use #tee instead) - Inline delete_first logic in Array#remove! to avoid dependency Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent ab29875 commit 9242533

5 files changed

Lines changed: 32 additions & 37 deletions

File tree

HISTORY.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ Changes:
1515
* Add `Array#indexes` / `Array#index_all` to find all matching indexes. (PR#294)
1616
* Add `String#dashcase` for kebab-case conversion. (PR#297)
1717
* Add `Binding#caller_locations`.
18+
* Add `Kernel#tee` — block-less method chaining via Tee/Functor, replaces `tap` override.
19+
* Add `Tee` as alias for `Functor` (gradual rename).
1820

1921
* Improved Features
2022

@@ -32,6 +34,7 @@ Changes:
3234

3335
* Removals
3436

37+
* Remove `Kernel#tap` override. Use `Kernel#tee` for the block-less Functor form.
3538
* Remove `Enumerable#filter` (conflicts with Ruby's built-in `filter` since 2.6).
3639
Use `each_with_object` instead, with block arguments reversed:
3740
`collection.each_with_object([]) { |el, out| out << el if cond }`.

lib/core/facets/array/remove.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ def remove(other_ary)
3131
#
3232
def remove!(other_ary)
3333
other_ary.each do |el|
34-
delete_first(el)
34+
i = index(el)
35+
delete_at(i) if i
3536
end
3637
self
3738
end

lib/core/facets/functor.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,3 +90,9 @@ def method_missing(op, *args, &blk)
9090
end
9191

9292
end
93+
94+
# Tee is an alias for Functor. The name comes from the Unix `tee` command,
95+
# which forks a data stream — here it forks a method call for side effects
96+
# while passing the original receiver through. Functor will be gradually
97+
# deprecated in favor of Tee.
98+
Tee = Functor

lib/core/facets/kernel/tap.rb

Lines changed: 3 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,3 @@
1-
require 'facets/functor'
2-
3-
module Kernel
4-
5-
# The tap K-Combinator. This yields self -and- returns self.
6-
#
7-
# 'foo.yml'.tap{ |f| YAML.load(f) } #=> 'foo.yml'
8-
#
9-
# Unlike Ruby's definition, this rendition can be used as a higher
10-
# order message. This form allows a single call before returning
11-
# the receiver.
12-
#
13-
# YAML.tap.load_file('foo.yml').load_file('bar.yml')
14-
#
15-
# IMPORTANT: This is one of few core overrides in Facets.
16-
17-
def tap #:yield:
18-
if block_given?
19-
yield(self)
20-
self
21-
else
22-
Functor.new{ |op,*a,&b| self.send(op, *a, &b); self }
23-
end
24-
end
25-
26-
# Old Definition:
27-
#
28-
# def tap #:yield:
29-
# if block_given?
30-
# b.arity == 1 ? yield(self) : instance_eval(&b)
31-
# end
32-
# return self
33-
# end
34-
#
35-
36-
end
1+
# Facets no longer overrides Kernel#tap. Use Kernel#tee instead
2+
# for the block-less Functor/Tee form.
3+
require 'facets/kernel/tee'

lib/core/facets/kernel/tee.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
require 'facets/functor'
2+
3+
module Kernel
4+
5+
# Returns a Tee (Functor) that intercepts method calls, forwards
6+
# them to self for side effects, and returns self. This is like
7+
# a block-less version of #tap that allows method chaining.
8+
#
9+
# YAML.tee.load_file('foo.yml').load_file('bar.yml')
10+
#
11+
# This is analogous to the Unix `tee` command — the data flows
12+
# through while side effects are forked off.
13+
14+
def tee
15+
Tee.new{ |op,*a,&b| self.send(op, *a, &b); self }
16+
end
17+
18+
end

0 commit comments

Comments
 (0)