2010-03-18 12 views
6

questo è quello che sto cercando di fare:Ruby - È possibile passare un blocco come parametro come blocco effettivo a un'altra funzione?

def call_block(in_class = "String", &block) 
    instance = eval("#{in_class}.new") 
    puts "instance class: #{instance.class}" 
    instance.instance_eval{ block.call } 
end 


# --- TEST EXAMPLE --- 
# This outputs "class: String" every time 
"sdlkfj".instance_eval { puts "class: #{self.class}" } 

# This will only output "class: Object" every time 
# I'm trying to get this to output "class: String" though 
call_block("String") { puts "class: #{self.class}" } 

Nella riga in cui si dice "instance.instance_eval {} block.call", sto cercando di trovare un altro modo per rendere la nuova variabile di istanza eseguire istanza eval sul blocco. L'unico modo in cui posso pensare di farlo è passare istanza_eval al blocco originale, non come una variabile o altro, ma come un blocco reale come nell'esempio di test.

Qualche consiglio?

risposta

8

Sì. È possibile passare il blocco per l'altro metodo anteponendo la variabile blocco con una e commerciale in questo modo:

def foo &blk 
    # now, blk is a variable bound to a block object 
    bar &blk 
end 

Il motivo per il vostro stanno ottenendo "class: Object" è che Ruby utilizza scoping lessicale. Ciò significa che self in puts "class: #{self.class}" fa riferimento a main, il contesto predefinito.

+0

Cosa ??? Era così semplice? Hahaha, grazie! Sono rimasto bloccato su questo per giorni! :) –

+0

il termine da cercare era "parametri di blocco"; più facile col senno di poi però :) – Gishu

Problemi correlati