2013-03-12 7 views

Antwort

4

&foo versucht foo als Block an instance_exec zu übergeben, und Sie übergeben bereits einen expliziten Block. Auslassen von kaufmännischem Und sendet foo genau wie jedes andere Argument (außer dass es eine Proc Instanz ist). Also, versuchen Sie stattdessen:

instance_exec(1,2,3,foo) do |*args, block| 
    puts *args 
    block.call 
    puts "bar" 
end 

Das bedeutet auch, dass Sie so etwas wie zu tun:

bar = proc{ |*args, block| 
    puts *args 
    block.call 
    puts "bar" 
} 

instance_exec(1,2,3,foo,&bar) 

Und das gleiche Ergebnis.

Mehr Infos unter Difference between block and &block in Ruby

+2

Leider funktioniert das nicht für meinen Fall. Ich versuche, einen vorhandenen Proc so transparent zu umbrechen, dass ich seine Ausführungszeit verfolgen kann. Da ich keine Kontrolle über die Signatur des Proc-Wrappings habe, kann ich diese Methode nicht verwenden. Im Allgemeinen scheint dies jedoch ein guter Work-Around zu sein. – Ajedi32

2

Ich bin etwa 3 Jahre zu spät zu dieser Party, aber ich dachte, ich würde einen Ansatz teilen, dass wir Ihnen den inneren Block mehr wie ein echter Block behandeln, anstatt nur eine Ebene altes Argument.

Die beste Methode, die ich kenne, besteht darin, ein Objekt zu erstellen, das als Bindungskontext fungiert und den äußeren Block als Methode definiert. Also, wenn ich das Original Beispiel wie folgt umschreiben ohne instance_exec Aufruf ...

inner_proc = proc { puts "inner" } 
outer_proc = proc { |*args, &inner_block| 
    puts *args 
    inner_block.call 
    puts "bar" 
} 

Wir outer_proc als Methode für ein Objekt definieren können

scope_object = Object.new 
scope_object.define_singleton_method :bound_proc, &outer_proc 

Jetzt können Sie scope_object.bound_proc anstelle des instance_exec Anruf rufen über.

scope_object.bound_proc 1, 2, 3, &inner_proc 

Sie erhalten:

1 
2 
3 
inner 
bar 

Leider müssen Sie eine LocalJumpError erhalten, wenn Sie versuchen, innerhalb von outer_proc, anstatt die inner_block.call, ich bin mir nicht ganz sicher, warum zu erhalten. Wenn jemand diese Antwort hat, würde mich das interessieren.

+0

Es funktioniert! vielen Dank! – benjaminchanming