2010-03-18 14 views
6

Esto es lo que estoy tratando de hacer:Ruby: ¿es posible pasar un bloque como un param como un bloque real a otra función?

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}" } 

En la línea donde dice "instance.instance_eval {} block.call", que estoy tratando de encontrar otra manera de hacer que la nueva variable de instancia ejecutar instancia eval en el bloque. La única forma en que puedo pensar para lograrlo es pasar instance_eval al bloque original, no como una variable ni nada, sino como un bloque real como en el ejemplo de prueba.

¿Algún consejo?

Respuesta

8

Sí. Puede pasar el bloque al otro método anteponiendo la variable de bloque con una y comercial de este modo:

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

La razón están recibiendo su "clase: El objeto" es que Ruby utiliza ámbito léxico. Esto significa que auto en puts "class: #{self.class}" se refiere a main, el contexto predeterminado.

+0

¿Qué ??? Fue así de simple? ¡Jajaja gracias! ¡Estuve atrapado en esto por días! :) –

+0

el término a buscar era 'parámetros de bloque'; más fácil en retrospectiva, aunque :) – Gishu

Cuestiones relacionadas