Pozostałe odpowiedzi są dość dokładne, a Closures in Ruby obszernie omawia różnice funkcjonalne.Byłem ciekawy, która metoda byłaby najlepsza dla metod, które akceptują blok , opcjonalnie, więc napisałem kilka testów porównawczych (wyłączając this Paul Mucur post). I w porównaniu z trzech metod:
- & blok w metodzie podpisu
- Korzystanie
&Proc.new
- Owijanie
yield
w innym bloku
Oto kod:
require "benchmark"
def always_yield
yield
end
def sometimes_block(flag, &block)
if flag && block
always_yield &block
end
end
def sometimes_proc_new(flag)
if flag && block_given?
always_yield &Proc.new
end
end
def sometimes_yield(flag)
if flag && block_given?
always_yield { yield }
end
end
a = b = c = 0
n = 1_000_000
Benchmark.bmbm do |x|
x.report("no &block") do
n.times do
sometimes_block(false) { "won't get used" }
end
end
x.report("no Proc.new") do
n.times do
sometimes_proc_new(false) { "won't get used" }
end
end
x.report("no yield") do
n.times do
sometimes_yield(false) { "won't get used" }
end
end
x.report("&block") do
n.times do
sometimes_block(true) { a += 1 }
end
end
x.report("Proc.new") do
n.times do
sometimes_proc_new(true) { b += 1 }
end
end
x.report("yield") do
n.times do
sometimes_yield(true) { c += 1 }
end
end
end
wydajność była podobna między Ruby 2.0.0p247 i 1.9.3p392. Oto wyniki dla 1.9.3:
user system total real
no &block 0.580000 0.030000 0.610000 ( 0.609523)
no Proc.new 0.080000 0.000000 0.080000 ( 0.076817)
no yield 0.070000 0.000000 0.070000 ( 0.077191)
&block 0.660000 0.030000 0.690000 ( 0.689446)
Proc.new 0.820000 0.030000 0.850000 ( 0.849887)
yield 0.250000 0.000000 0.250000 ( 0.249116)
dodanie wyraźnego &block
param kiedy to nie zawsze naprawdę nie spowolnić metody. Jeśli blok jest opcjonalny, nie dodawaj go do podpisu metody. I, dla przechodzenia bloków wokół, owijanie yield
w innym bloku jest najszybsze.
To powiedziawszy, są to wyniki dla miliona powtórzeń, więc nie przejmuj się tym zbytnio. Jeśli jedna metoda uczyni twój kod bardziej przejrzystym kosztem jednej milionowej sekundy, użyj go w każdym razie.
Nota boczna: 'def trzykrotnie (& blok)' jest bardziej samo-dokumentujące, szczególnie w stosunku do 'plonu' pochowanego gdzieś w dużej metodzie. –