Enumerable::Enumerator#each2009/11/26

each {...} -> object

   生成時のパラメータに従ってブロックを繰り返します。生成時に指定したイテレータの戻り値をそのまま返します。
Enumerable::Enumerator#each

戻り値が元のメソッドの戻り値というのが面白い。

str = "Hello World!"
enum = str.gsub(/./)
out = enum.each{|c| p c; c.downcase} #=> "H"
                                     #   "e"
                                     #   "l"
                                     #   "l"
                                     #   "o"
                                     #   " "
                                     #   "W"
                                     #   "o"
                                     #   "r"
                                     #   "l"
                                     #   "d"
                                     #   "!"
p out #=> "hello world!"

Enumerable::Enumerator#each に与えたブロックが yeild される際には Enumerator生成に使った元のメソッドの副作用もちゃんと適用されているようで、 このgsubの場合では、$&等の組み込み変数もちゃんと変更されている。

str = "Hello World!"
enum = str.gsub(/./)
out = enum.each{p $&} #=> "H"
                      #   "e"
                      #   "l"
                      #   "l"
                      #   "o"
                      #   " "
                      #   "W"
                      #   "o"
                      #   "r"
                      #   "l"
                      #   "d"
                      #   "!"
p out #=> nil

問題は、Kernel#gsub に Enumerable::Enumerator を返却するインターフェイスが無いことか……。

$_ = "Hello World!"
not_enum = gsub(/./)
p not_enum #=> "Hello World!"
p not_enum.class #=> String