2009-11-25 8 views
6

No conozco a ningún Ruby y estoy leyendo documentación sobre él ahora. Una duda que acabo de leer sobre el uso de bloques de código y la palabra clave "rendimiento" es si es posible pasar más de un bloque de código a una función, y usar ambos a voluntad desde dentro de la función llamada.¿Cómo pasar más un bloque de código a una función en Ruby?

Respuesta

9

Puede pasar solo un bloque a la vez, pero los bloques son en realidad instancias Proc y puede pasar tantas instancias como desee.

def mymethod(proc1, proc2, &block) 
    proc1.call 
    yield if block_given? 
    proc2.call 
end 

mymethod(Proc.new {}, Proc.new {}) do 
    # ... 
end 

Sin embargo, rara vez tiene sentido.

+1

Los bloques no son exactamente procesos. Tienen usos y sintaxis comunes, pero tienen suficientes diferencias de implementación como para causar un comportamiento confuso. Es un poco pedante, pero la diferencia de alcance me ha mordido antes. – fengb

+0

@fengb Acabo de hacer una prueba. http://gist.github.com/242746 ¿Tiene más documentación sobre la diferencia entre Proc y block? Ruby me dice que un bloque es un Proc. –

+0

Los bloques se "incrustan" de forma implícita en proc utilizando la sintaxis & var. Pero hay ciertas operaciones que se comportan de manera diferente cuando se usan como un bloque en comparación con un proceso. Comparación larga pero exhaustiva: http://innig.net/software/ruby/closures-in-ruby.rb – fengb

1

Sintácticamente, el uso de la instrucción yield solo admite un bloque de código que se transfiere a la función.

Por supuesto, puede pasarle una función a otras funciones múltiples o "objetos de bloque de código" (objetos Proc), y usarlos, pero no simplemente usando yield.

1

Puedes crear objetos Proc y pasar tantos como quieras.

Recomiendo leer this page para comprender las sutilezas de todas las construcciones diferentes de bloque y cierre Ruby has.

1

Usted puede utilizar el método call en lugar de rendimiento para manejar dos bloques separados aprobadas en

Así es como:.

def mood(state, happy, sad) 
    if (state== :happy) 
    happy.call 
    else 
    sad.call 
    end 
end 

mood(:happy, Proc.new {puts 'yay!'} , Proc.new {puts 'boo!'}) 
mood(:sad, Proc.new {puts 'yay!'} , Proc.new {puts 'boo!'}) 

Puede pasar argumentos por ejemplo:

happy.call('very much') 

los argumentos funcionan tal como se esperaría en los bloques:

Proc.new {|amount| puts "yay #{amount} !"} 
Cuestiones relacionadas