Ich muss einen Block von einer Methode zu einer anderen übergeben (Ich möchte Rails.cache.fetch
mit Block an meine Methode übergeben).Block von einer Methode zur anderen übergeben
Ich kann &block
entweder zur Parameterliste hinzufügen und diese verwenden, um sie an die nächste Methode zu übergeben, oder ich kann einen neuen Block erstellen und Ausbeute in ihm aufrufen. Ich habe geschrieben ein kurzes Beispiel und Benchmark:
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)
Sieht aus wie { yield }
Ansatz viel schneller. Ist es der richtige Weg? Gibt es irgendwelche Probleme, die ich nicht kenne, weil ich in einem neu erstellten Block yield
aufgerufen habe?
Sie haben 'Proc', und das spezialisierte' Proc', das 'Lambda' ist, das Sie auch verwenden können. Eine Methode ist auch ein Block, aber zunächst kein Objekt. Sie können eine Methode in ein 'Method'-Objekt konvertieren. Sie haben mehr Möglichkeiten als nur die zwei Möglichkeiten, einen Block zu übergeben. Also ich denke deine Frage ist etwas unvollständig. Es gibt keine besonderen Überlegungen bei der Weitergabe eines anonymen Blocks, außer dass nicht auf den Namen zugegriffen wird (außerhalb der Methode), obwohl Procs und Lambdas beide als "anonym" betrachtet werden, denke ich. – vgoff
'Ausbeute' ist in der Tat schneller. Gerade weil es weniger funktional ist. Sie können den übergebenen Block nur aufrufen. Sie können es beispielsweise nicht an die nächste Methode weitergeben. Dein Test macht keinen Sinn, übrigens. 'do_something' verwendet den Block nicht. –
@SergioTulentsev Sie können es übergeben, indem Sie es aufrufen. 'Klasse Array; def meine_map; Karte {| e | Ausbeute (e)} Ende ende. – sawa