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:複数の引数が取れないなど