2009-08-28 19 views
43

Quiero crear un filtro y poder aplicarlo a una matriz o hash. Por ejemplo:¿Cómo creo un bloque/proc/lambda reutilizable en Ruby?

def isodd(i) 
    i % 2 == 1 
end 

La quiero ser capaz de utilizarlo como tal:

x = [1,2,3,4] 
puts x.select(isodd) 
x.delete_if(isodd) 
puts x 

Esta parece que debería ser simple, pero no puedo averiguar lo que tengo que hacer lo hace funcionar

Respuesta

68

Crear un lambda y luego convertir a un bloque con el & operador:

isodd = lambda { |i| i % 2 == 1 } 
[1,2,3,4].select(&isodd) 
+3

También puede usar el operador "stabby lambda" para crear el proceso independiente. Ver http://stackoverflow.com/questions/9340117/what-is-the-stab-operator-in-ruby. Disponible a partir de 'ruby 1.9'. Por supuesto, puramente una cuestión de gusto y estilo de codificación :) – zealoushacker

+0

para aquellos que leen en el futuro, también se pueden crear lambdas como este: lambda_name = ->() {puts "hello world"} – BKSpurgeon

18

Se puede crear un nombre Proc y pasarlo a los métodos que toman bloques:

isodd = Proc.new { |i| i % 2 == 1 } 
x = [1,2,3,4] 
x.select(&isodd) # returns [1,3] 

El & el operador convierte entre Proc/lambda y un bloque, que es lo que los métodos como select esperan.

27
puts x.select(&method(:isodd)) 
+0

Las respuestas de Dave y Daniel también son buenas. Esta es una alternativa. –

+2

+1 La respuesta es útil para cuando tiene un método existente que no desea reescribir como lambda/proc. También funciona si el método necesita ser llamado en un objeto específico: 'x.select (& obj.method (: isodd))' – Kelvin

+0

nice y esto responde correctamente a la pregunta planteada - ellos querían saber cómo envolver un existente método y pasarlo como un proceso – Dan