2012-07-03 13 views
5

Suponiendo Tengo el siguiente proc:¿Cómo pasar un bloque a otro en Ruby?

a = Proc.new do 
    puts "start" 
    yield 
    puts "end" 
end 

también asumiendo que pase a a otro método que llama posteriormente instance_eval en otra clase con ese bloque, ¿cómo puedo ahora pasar a un bloque en el extremo de que el método que se cedido en a.

Por ejemplo:

def do_something(a,&b) 
    AnotherClass.instance_eval(&a) # how can I pass b to a here? 
end 

a = Proc.new do 
    puts "start" 
    yield 
    puts "end" 
end 

do_something(a) do 
    puts "this block is b!" 
end 

salida debe, por supuesto, debe ser:

start 
this block is b! 
end 

¿Cómo puedo pasar el bloque secundario a una en el instance_eval?

Necesito algo como esto para la base de un sistema de plantillas de Ruby en el que estoy trabajando.

+0

posible duplicado de [Trouble produciendo dentro de un bloque/lambda] (http://stackoverflow.com/questions/4982630/trouble-yielding-inside-a-block-lambda) –

Respuesta

5

No puede usar yield en a. Por el contrario, debe pasar un objeto Proc. Este sería el nuevo código:

def do_something(a,&b) 
    AnotherClass.instance_exec(b, &a) 
end 

a = Proc.new do |b| 
    puts "start" 
    b.call 
    puts "end" 
end 

do_something(a) do 
    puts "this block is b!" 
end 

yield es sólo para los métodos. En este nuevo código, utilicé instance_exec (nuevo en Ruby 1.9) que le permite pasar parámetros al bloque. Por eso, podemos pasar el objeto Proc b como un parámetro al a, que puede llamarlo con Proc#call().

0
 
a=Proc.new do |b| 
    puts "start" 
    b.call 
    puts "end" 
end 
def do_something(a,&b) 
    AnotherClass.instance_eval { a.call(b) } 
end 
+0

Eso no funcionará. 'instance_eval' no captura las variables de la misma manera que los bloques normales. – Linuxios

Cuestiones relacionadas