rails objetos metodos manejo lista importar for clases bucle ruby

ruby - objetos - ¿Cómo salir de un bloque de rubí?



ruby for bucle (7)

Para romper el bucle o salir del bucle simplemente use regreso next palabra clave devolver si element.nil? next if element.nil?

Aquí está la Bar#do_things :

class Bar def do_things Foo.some_method(x) do |x| y = x.do_something return y_is_bad if y.bad? # how do i tell it to stop and return do_things? y.do_something_else end keep_doing_more_things end end

Y aquí está Foo#some_method :

class Foo def self.some_method(targets, &block) targets.each do |target| begin r = yield(target) rescue failed << target end end end end

Pensé en usar raise, pero estoy tratando de hacerlo genérico, así que no quiero poner nada específico en Foo .


Quería simplemente poder salir de un bloque, algo así como un goto hacia adelante, no realmente relacionado con un bucle. De hecho, quiero separarme de un bloque que está en un bucle sin terminar el bucle. Para hacer eso, hice del bloque un bucle de una iteración:

for b in 1..2 do puts b begin puts ''want this to run'' break puts ''but not this'' end while false puts ''also want this to run'' end

Espero que esto ayude al próximo googler que aterrice aquí basado en la línea de asunto.


Quizás pueda usar los métodos incorporados para encontrar elementos particulares en un Array, en lugar de targets de each y hacer todo a mano. Algunos ejemplos:

class Array def first_frog detect {|i| i =~ /frog/ } end def last_frog select {|i| i =~ /frog/ }.last end end p ["dog", "cat", "godzilla", "dogfrog", "woot", "catfrog"].first_frog # => "dogfrog" p ["hats", "coats"].first_frog # => nil p ["houses", "frogcars", "bottles", "superfrogs"].last_frog # => "superfrogs"

Un ejemplo sería hacer algo como esto:

class Bar def do_things Foo.some_method(x) do |i| # only valid `targets` here, yay. end end end class Foo def self.failed @failed ||= [] end def self.some_method(targets, &block) targets.reject {|t| t.do_something.bad? }.each(&block) end end


Si desea que su bloque devuelva un valor útil (por ejemplo, cuando use #map , #inject , etc.), next y break también aceptan un argumento.

Considera lo siguiente:

def contrived_example(numbers) numbers.inject(0) do |count, x| if x % 3 == 0 count + 2 elsif x.odd? count + 1 else count end end end

El equivalente utilizando next :

def contrived_example(numbers) numbers.inject(0) do |count, x| next count if x.even? next (count + 2) if x % 3 == 0 count + 1 end end

Por supuesto, siempre puede extraer la lógica necesaria en un método y llamarla desde dentro de su bloque:

def contrived_example(numbers) numbers.inject(0) { |count, x| count + extracted_logic(x) } end def extracted_logic(x) return 0 if x.even? return 2 if x % 3 == 0 1 end


Utilice la palabra clave next . Si no desea continuar con el siguiente elemento, use break .

Cuando se usa next dentro de un bloque, hace que el bloque salga de inmediato, devolviendo el control al método del iterador, que puede comenzar una nueva iteración invocando el bloque nuevamente:

f.each do |line| # Iterate over the lines in file f next if line[0,1] == "#" # If this line is a comment, go to the next puts eval(line) end

Cuando se usa en un bloque, break transfiere el control fuera del bloque, fuera del iterador que invocó el bloque, y a la primera expresión que sigue a la invocación del iterador:

f.each do |line| # Iterate over the lines in file f break if line == "quit/n" # If this break statement is executed... puts eval(line) end puts "Good bye" # ...then control is transferred here

Y por último, el uso del return en un bloque:

return siempre hace que el método de encerrar regrese, sin importar cuán profundamente anidado esté dentro de los bloques (excepto en el caso de las lambdas):

def find(array, target) array.each_with_index do |element,index| return index if (element == target) # return from find end nil # If we didn''t find the element, return nil end


utilizar la palabra clave break lugar de return


next y el break parecen hacer lo correcto en este ejemplo simplificado!

class Bar def self.do_things Foo.some_method(1..10) do |x| next if x == 2 break if x == 9 print "#{x} " end end end class Foo def self.some_method(targets, &block) targets.each do |target| begin r = yield(target) rescue => x puts "rescue #{x}" end end end end Bar.do_things

salida: 1 3 4 5 6 7 8