TL;DR
Enumerable#lazy
(#force
)を使えばよかった。
つらいと思っていたところ
RubyのEnumerable#map
みたいな処理はついついチェインして書きたくなってしまうんだけど、毎回オブジェクトが作成されていて非効率で辛いと思っていた。
p 5.times.map { |n|
(n * 10).tap(&method(:puts))
}.select { |n|
(n > 20).tap(&method(:puts))
}.map { |n|
(n + 2).tap(&method(:puts))
}
=>
# 0
# 10
# 20
# 30
# 40
# false
# false
# false
# true
# true
# 32
# 42
# [32, 42]
そしたら
#lazy
というのがあった。
-p 5.times.map { |n|
+p 5.times.lazy.map { |n|
(n * 10).tap(&method(:puts))
}.select { |n|
(n > 20).tap(&method(:puts))
}.map { |n|
(n + 2).tap(&method(:puts))
-}
+}.force
いい感じに遅延実行してくれる。
p 5.times.lazy.map { |n|
(n * 10).tap(&method(:puts))
}.select { |n|
(n > 20).tap(&method(:puts))
}.map { |n|
(n + 2).tap(&method(:puts))
}.force
=>
# 0
# false
# 10
# false
# 20
# false
# 30
# true
# 32
# 40
# true
# 42
# [32, 42]
バッチとか書くときにいいかも。
自分が情弱なだけだったけど知らない人もいそう。