Bye Bye Moore

猫マンション建築の野望を胸に零細事業主として資本主義の荒波に漕ぎ出したアラサー男の技術メモ

each_with_objectで遊ぶ

each_with_objectには、文字通りオブジェクトを持たせてeachをブンまわすことができます。
以前も扱った内容ですが……ちょっと理解が深まったので再度。

文字列

> ('a'..'z').each_with_object("") {|i,a| a << i.upcase}
=> "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

p ("a".."z").each_with_object(".png").map(&:+)
["a.png", "b.png", "c.png",  ...(中略)... "y.png", "z.png"]
=> ["a.png", "b.png", "c.png",   ...(中略)..."y.png", "z.png"]

正規表現

> %w(foo bar fizz buzz).each_with_object(/fizz/) {|i,rg| puts rg === i }
false
false
true
false
=> /fizz/

配列

これはあまり旨味がないかもしれません。mapとかありますし。

> (1..10).each_with_object([2,9]) {|i,a| puts  (i * (a[0]) + a[1]) }
11
13
15
17
19
21
23
25
27
29
=> [2, 9]

あとは

> (1..100).each_with_object([]) {|i,a| a << i * 2 }
=> [2, 4, 6, 8, 10, 12, 14, 16, ...(中略)... 194, 196, 198, 200]

この例程度の話であれば

> (1..100).each_with_object(2).map(&:*)
=> [2, 4, 6, 8, 10, 12, 14, 16, ...(中略)... 194, 196, 198, 200]

と書き換えできます。
少しだけ文字数が減りました。

数値

> (1..10).each_with_object(2) {|i,a| puts a += i}
3
4
5
6
7
8
9
10
11
12
=> 2

sleep

rubyは何でもobjectです。
というわけで、何に使うのか検討もつきませんが、sleepを持たせる事も可能です。
最初の一回だけ待ち、あとは数値を返すだけ。*1

> (1..5).each_with_object(sleep(5)) {|i,a| puts i; p a}
1
5
2
5
3
5
4
5
5
5
=> 5

*1:p sleep 5の返り値は5です