いつもの如くgemリーディングを行っていたらこんなコードに出くわした

1 def define_route path, options, &block
2   self.route_defs << [path, options, Proc.new(&block)]
3 end

おやProc.new(&block)て意味ないのでは..

1 def define_route path, options, &block
2   self.route_defs << [path, options, block]
3 end

そもそも引数の&blockProcに変換しているので、この様にProc.newしなくても、そのまま変換されたものを渡せばいいのでは

1 Proc.new{ "kakuremi" }

Proc.newを使う場合はブロックを直接渡すか

1 def ninpo
2   Proc.new
3 end
4 
5 ninpo do
6   "kakuremi"
7 end

こんな感じでninpoに渡されたブロックを元にProcを作成するのであって、この場合はninpoの引数にブロックは必要ない。なので

1 def define_route path, options, &block
2   self.route_defs << [path, options, block]
3 end

もしくは

1 def define_route path, options
2   self.route_defs << [path, options, Proc.new]
3 end

でも良い。ただ引数にブロックを明示的に宣言した方が、親切なので後者より前者が良いと思います。
まぁでも先のコード書いた人の意図としては、Procオブジェクトであるのにblockという変数名で配列に収めるのが気持ち悪かったのだろう。分からなくないでもありません。しかしブロックはオブジェクトではないので変数名がblockである時点でそれはもうProcなのですよ。それに「事情があってProc.new(&block)で新たなオブジェクトを作ろうとしているのでは」とミスリーディングする恐れがある。

1 def ninpo &block
2   block.equal? Proc.new(&block) # => true
3 end
4 
5 ninpo do
6   "kakuremi"
7 end

残念ながらProc.newしても同じブロックが生成要素なら同じオブジェクトなのです。(rubyいいぞぉ〜〜〜)
そもそもProcよりlambdaのほうが好みだ。もっというなら->の方がかっこいい。脱線乙。




comments powered by Disqus


© 2015 kyuden