Rubyのpでメソッドチェーンを覗き見よう!

Rubyでメソッドチェーンの途中経過を覗き見るには
Kernel#tapが便利だよね

 (1..10).tap{ |x| puts x.inspect }
        .to_a.tap{ |x| puts x.inspect }
        .select { |x| x % 2 == 0 }.tap{ |x| puts x.inspect }
        .map { |x| x * x }.tap{ |x| puts x.inspect }
 
 # >> 1..10
 # >> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
 # >> [2, 4, 6, 8, 10]
 # >> [4, 16, 36, 64, 100]

tapのブロックにはもちろんいろいろな手続が書けるけど
やっぱり出力系メソッドがよく使われると思うんだ


それならいっそのこと
それらのメソッドがselfを返すようにして
しかも引数を取らないときには
selfが引数になるようにしたら
もっと簡単になるんじゃないかと思ったんだ

 module Kernel
   [:p, :puts].each do |m|
     alias :"__#{m}__" :"#{m}"
     define_method(m) do |obj=self|
       instance_eval "__#{m}__(obj)"
       self
     end
   end
 end


こうしておけば
先の例は次のように書けるんだよ

 (1..10).p.to_a.p.select { |x| x % 2 == 0 }.p.map { |x| x * x }.p
 
 # >> 1..10
 # >> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
 # >> [2, 4, 6, 8, 10]
 # >> [4, 16, 36, 64, 100]

どうかな?


他の例も示しておくね

 %w(google twitter facebook).map(&:capitalize).puts.map(&:upcase) # => ["GOOGLE", "TWITTER", "FACEBOOK"]
 
 # >> Google
 # >> Twitter
 # >> Facebook
 
 
 require "mathn"
 Prime.each(30).map(&:p)
 
 # >> 2
 # >> 3
 # >> 5
 # >> 7
 # >> 11
 # >> 13
 # >> 17
 # >> 19
 # >> 23
 # >> 29
 
 
 class Array
   def to_h
     Hash[self]
   end
 end
 
 [:GOOG,:YHOO,:MSFT].zip(['google','yahoo','microsoft']).p
                    .to_h.p
                    .each_with_object({}) { |(k,v), h| h[k] = "www.#{v}.com" }.p
 
 # >> [[:GOOG, "google"], [:YHOO, "yahoo"], [:MSFT, "microsoft"]]
 # >> {:GOOG=>"google", :YHOO=>"yahoo", :MSFT=>"microsoft"}
 # >> {:GOOG=>"www.google.com", :YHOO=>"www.yahoo.com", :MSFT=>"www.microsoft.com"}

先の実装だとオリジナルのメソッドに
ちょっと制限が掛かっちゃうけど*1
簡単に途中経過を見れるのはよさそうだよね


既出のアイディアだったら許してね


(追記:2011-6-26) やっぱりありました ^^; こちらはpの拡張ではないのですが、まあ発想は同じです。https://github.com/esminc/tapp (https://twitter.com/#!/mori_dev/status/84845033634799616)

*1:複数の引数が取れないなど