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.
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