redundancy in method_missing

Looking through the rails core code, I see method_missing performed like this a lot:

def method_missing(method, *args) if block_given? current_status.send(method, *args) { |*block_args| yield(*block_args) } else current_status.send(method, *args) end end

Why not just write:

def method_missing(method, *args, &block) current_status.send(method, *args, &block) end

Building the proc object (as implied by the use of &block) is more expensive than just passing a block:

require 'benchmark' include Benchmark

def dummy()   yield end def dummy_proc(&block)   block.call end

bm do |x|   x.report('with yield'){ 100000.times { dummy {y=1}}}   x.report('with &block') { 100000.times { dummy_proc {y=1}}} end

outputs (on a fairly elderly machine):

      user system total real with yield 0.420000 0.000000 0.420000 ( 0.464097) with &block 2.340000 0.040000 2.380000 ( 2.584321)

Fred

Fred, thanks for that, I still can't believe that block.call is slower than yield.

If my memory is correct, it's not the block call (try removing the
yield/block.call from the benchmark) that is slow, but the coercing of
the block into a proc

Fred