将块从一种方法传递到另一种方法

时间:2016-04-20 10:28:11

标签: ruby proc

我需要将一个块从一个方法传递给另一个方法(我想通过传递给我的方法的块调用Rails.cache.fetch。)

我可以将&block添加到参数列表中并使用它将其传递给下一个方法,或者我可以创建一个新块并在其中调用yield。我写了一个简短的例子和基准:

require "benchmark"

def with_block(&block)
  do_something 'Test', &block
end

def with_yield
  do_something('Test') { yield }
end

def do_something(string)
  "#{yield} #{string}"
end

n = 5_000_000
Benchmark.bmbm do |x|
  x.report("&block") do
    n.times { with_block { "Yo" } }
  end
  x.report("yield") do
    n.times { with_yield { "Yo" } }
  end
end


&block   3.320000   0.010000   3.330000 (  3.340438)
yield    1.670000   0.000000   1.670000 (  1.669504)
--------------------------------- total: 5.000000sec

             user     system      total        real
&block   3.270000   0.010000   3.280000 (  3.275914)
yield    1.680000   0.000000   1.680000 (  1.682768)

看起来{ yield }方法要快得多。这是正确的方法吗?由于在新创建的块中调用yield,我是否有任何遗漏?

1 个答案:

答案 0 :(得分:3)

简短回答:始终使用yield,除非您有充分理由明确引用&block

请参阅:Why blocks make ruby methods 439% slower

使用&block,您可以获得一个具体化的Proc,您可以在其中执行各种stuff并可以移动。但是,使用yield和隐式块,您只能调用块。

通过使用yield,解释器可以绕过所有的Proc,因为它知道开发人员将无法使用它;因此它只能保留一个C级结构,而不必设置一个Ruby级别的对象。