Я раньше работал с кем-то, кто сказал, "если компилятор к немому для выяснения то, что Вы пытаетесь сделать и не можете оптимизировать его, Ваш компилятор повреждается, и пора получить новое". Я уверен, что существуют пограничные случаи, когда блок разобьет Ваш код C, но если Вы часто используете ассемблер "победить" по Вашему компилятору, Ваш компилятор арестован.
То же может быть сказано для записи "оптимизированного" SQL, который пытается принудить планировщика запроса в выполнение вещей. Если Вы перестраиваете запросы заставлять планировщика делать то, что Вы хотите, Ваш планировщик запроса арестован - получают новый.
То, что вам нужно, это нелокальный поток управления, для чего у Ruby есть несколько вариантов:
throw
/ ] catch
Продолжения
Плюсы:
GOTO
. Минусы:
Исключения
Плюсы:
Минусы:
throw
/ catch
Это (примерно) то, как это будет выглядеть:
catch :aaa do
stuff.each do |otherstuff|
foo.each do |bar|
throw :aaa if somethingbad
end
end
end
Плюсы:
StopIteration
для завершения. Минусы:
Рассмотрим throw
/ catch
. Обычно внешний цикл в приведенном ниже коде выполняется пять раз, но с помощью throw вы можете изменить его на все, что захотите, сломав его в процессе. Рассмотрим этот совершенно допустимый рубиновый код:
catch (:done) do
5.times { |i|
5.times { |j|
puts "#{i} #{j}"
throw :done if i + j > 5
}
}
end
Нет, нет.
Возможны следующие варианты:
Я знаю, что пожалею об этом утром, но простое использование цикла while может помочь.
x=0
until x==10
x+=1
y=0
until y==10
y+=1
if y==5 && x==3
x,y=10,10
end
end
break if x==10
puts x
end
if y == 5 && x == 3
- это только пример выражение становится правдой.
Может, это то, что вам нужно? (не проверено)
stuff.find do |otherstuff|
foo.find do
somethingbad() && AAA
end
end
Метод find продолжает цикл до тех пор, пока блок не вернет ненулевое значение или не будет достигнут конец списка.