2013-03-27 8 views
5

Ich habe eine Reihe von Methoden, die ich so nennen:einen Block in Methodenaufrufe Wrapping, die Blöcke mit Namen akzeptieren

with_this do 
    with_that do 
    and_in_this_context do 
     yield 
    end 
    end 
end 

Ich erinnere mich, es einen Trick war rekursiv einen solchen Block Anruf zu wickeln. Wie schreibe ich eine Methode, die das Umbrechen für mich blockiert?

def in_nested_contexts(&blk) 
    contexts = [:with_this, :with_that, :and_in_this_context] 
    # ... magic probably involving inject 
end 

Antwort

3

Sie können in der Tat inject zu erstellt verschachtelte lambdas oder Procs verwenden, die Sie am Ende aufrufen können. Sie benötigen gegebenen Block das Innere des Nestes zu sein, so dass Sie Ihre Array umkehren und diesen Block als Anfangswert verwenden, wickeln Sie dann jede aufeinanderfolgende Funktion um das Ergebnis von inject:

def in_nested_contexts(&blk) 
    [:with_this, :with_that, :and_in_this_context].reverse.inject(blk) {|block, symbol| 
    ->{ send symbol, &block } 
    }.call 
end 

Wenn Sie Ihre with_this wickeln , et al Methoden mit vor und nach puts Aussagen, können Sie dies in Aktion sehen:

in_nested_contexts { puts "hello, world" } 
#=> 
    with_this start 
    with_that start 
    context start 
    hello, world 
    context end 
    with_that end 
    with_this end 
+0

Genau das, was ich brauchte, danke! – Julik