2011-07-30 9 views
5

Me gustaría ser capaz de ceder dentro de un bloque enumerable, con el fin de crear un código de referencia de referencia repetitivo.Ruby: Rendimiento dentro de enumerable

Básicamente me gustaría hacer algo esto (simplificado):

def iterator(enumerable, &block) 
    iterations = enumerable.size 
    counter = 0 
    enumerable.each do |item| 
    counter +=1 
    puts "Iterating #{counter}/#{iterations}..." 
    yield 
    end 
end 

Entonces me gustaría ser capaz de utilizar este método con el fin de envolver el código repetitivo evaluación comparativa alrededor de un bloque estaría la iteración, por lo que podría llamar algo así como:

# assuming foo is an enumerable collection of objects 
iterator foo do 
    item.slow_method 
    item.mundane_method 
    item.save 
end 

... y cuando el código ejecutado me gustaría tener la siguiente salida del registro:

Iterating 1/1234... 
Iterating 2/1234... 
Iterating 3/1234... 

Parece que este tipo de cosas debe ser posible, pero no he podido descifrar la sintaxis ni a qué se llama (para buscarla).

El problema es que necesito ajustar el texto estándar FUERA del objeto enumerable que se va a iterar, y también DENTRO del bloque de iteración. Puedo pasar un objeto enumerable muy bien, pero parece que no puedo invocar métodos sobre los objetos iterados desde dentro del bloque en el que paso.

Espero que esta explicación tenga sentido, me está costando describirlo eso. Por favor, deje comentarios si necesita aclaración sobre algo, voy a tratar de explicar mejor.

+0

es posible que desee utilizar 'enumerable.zip (1..size) .Cada hacer | tema, contador | para un código de aspecto "más limpio". –

Respuesta

7

declaración de Ruby yield puede tomar argumentos. Usted querría decir

yield item 

Esto pasa el elemento "actual" a su bloque "exterior".

Espero haber entendido la pregunta correctamente.

ADENDA

Y aquí es el código para mostrar en acción:

class Item 
    def initialize(id) 
    @id = id 
    end 
    def slow_method() 
    puts "slow #@id" 
    end 
    def mundane_method() 
    puts "mundane #@id" 
    end 
    def save() 
    puts "save #@id" 
    end 
end 

foo = [Item.new(100), Item.new(200), Item.new(300)] 

def iterator(enumerable, &block) 
    iterations = enumerable.size 
    counter = 0 
    enumerable.each do |item| 
    counter +=1 
    puts "Iterating #{counter}/#{iterations}..." 
    yield item 
    end 
end 

iterator foo do |item| 
    item.slow_method 
    item.mundane_method 
    item.save 
end 
+0

Eso lo solucionó, esto es exactamente lo que necesitaba saber. ¡Gracias! – Andrew

Cuestiones relacionadas