lazy
がない場合、無限リストを素朴に使おうとすると死んでしまう場合が多い。
a=(1..5).cycle
b=%w( foo bar baz hoge ).cycle
z = a.zip(b) # ここで死亡
# ここから先は unreachable.
z11 = z.take(11)
p z11.map{ |i| i.join }.to_a.join(",")
上の例の場合、 zip
が無限に長いリストをメモリ上に作成しようとして死ぬんだと思う。
lazy
をつけると、生還する。
a=(1..5).cycle.lazy # ここで lazy
b=%w( foo bar baz hoge ).cycle
z = a.zip(b) # 生還!
z11 = z.take(11)
p z11.map{ |i| i.join }.to_a.join(",")
#=> "1foo,2bar,3baz,4hoge,5foo,1bar,2baz,3hoge,4foo,5bar,1baz"
to_a
で lazy な世界から普通の世界に帰ってくる。
※ force
でもいい。
帰ってくる前に take(11)
で個数が確定しているので、zip
が無限に長いリストを作らずに済む。
ということなんだと思う。