How to break outer cycle in Ruby?
What you want is non-local control-flow, which Ruby has several options for doing:
- Continuations,
- Exceptions, and
throw
/catch
Continuations
Pros:
- Continuations are the standard mechanism for non-local control-flow. In fact, you can build any non-local control-flow (subroutines, procedures, functions, methods, coroutines, state machines, generators, conditions, exceptions) on top of them: they are pretty much the nicer twin of
GOTO
.
Cons:
- Continuations are not a mandatory part of the Ruby Language Specification, which means that some implementations (XRuby, JRuby, Ruby.NET, IronRuby) don't implement them. So, you can't rely on them.
Exceptions
Pros:
- There is a paper that proves mathematically that Exceptions can be more powerful than Continuations. IOW: they can do everything that continuations can do, and more, so you can use them as a replacement for continuations.
- Exceptions are universally available.
Cons:
- They are called "exceptions" which makes people think that they are "only for exceptional circumstances". This means three things: somebody reading your code might not understand it, the implementation might not be optimized for it (and, yes, exceptions are godawful slow in almost any Ruby implementation) and worst of all, you will get sick of all those people constantly, mindlessly babbling "exceptions are only for exceptional circumstances", as soon as they glance at your code. (Of course, they won't even try to understand what you are doing.)
throw
/catch
This is (roughly) what it would look like:
catch :aaa do
stuff.each do |otherstuff|
foo.each do |bar|
throw :aaa if somethingbad
end
end
end
Pros:
- The same as exceptions.
- In Ruby 1.9, using exceptions for control-flow is actually part of the language specification! Loops, enumerators, iterators and such all use a
StopIteration
exception for termination.
Cons:
- The Ruby community hates them even more than using exceptions for control-flow.
How to break inner loop and next for outer loop in ruby?
I got something in the similar matter:
count = 0
10.times do |i|
(i..20).collect{ |ii| ii < rand(30) || break } || next
count += 1
end
So it is just boolean algebra. if
condition is taken place, when all
, i.e. result of collect
method, isn't nil
, so we need to next
keyword worked, when result of collect
is nil
. Therefore we just set or
operator between collect
and next
, in order to next
is occuring when result of collect
is nil
.
How to break from a nested loop to a parent loop that is more than one level above which requires a value provided by the nested loop
You can use multiple break
statements.
For example:
xxx.delete_if do |x|
result = yyy.each do |y|
result2 = zzz.each do |z|
if x + y == z
break true
end
end
break true if result2 == true
end
result == true
end
However I would definitely avoid this in your particular situation.
You shouldn't be assigning variables to the result of each
. Use map
, reduce
, select
, reject
, any?
, all?
, etc. instead
It makes more sense to use any?
to accomplish the same purpose:
xxx.delete_if do |x|
yyy.any? do |y|
zzz.any? do |z|
x + y == z
end
end
end
How to skip outer loop in ruby?
You can write:
array_1.each do |a1|
next if array_2.any? { |a2| a1.include?(a2) }
...
end
How to break out from a ruby block?
Use the keyword next
. If you do not want to continue to the next item, use break
.
When next
is used within a block, it causes the block to exit immediately, returning control to the iterator method, which may then begin a new iteration by invoking the block again:
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
When used in a block, break
transfers control out of the block, out of the iterator that invoked the block, and to the first expression following the invocation of the iterator:
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
And finally, the usage of return
in a block:
return
always causes the enclosing method to return, regardless of how deeply nested within blocks it is (except in the case of 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
Ruby/Rails break out of method inside loop
You have a couple of options for breaking out of a loop. Most simply, you can use break
or return
in your looping code.
In the context of your example above, it might be easier, if possible within the larger context of your application, to do the following:
def export_all
Category.find_each do |c|
begin
export_category(c)
rescue SpecificErrorIsBetterThanGenericExceptionIfPossible => e
break
end
end
end
def export_category(c)
sync_category(c)
end
It appears from your question that you want the loop in your export_all method to break when an exception is encountered. In such a case, I prefer my break/error handling code at that level.
Jump to next iteration of outer loop
This may be a bit redundant, but to better understand your question, I did:
quantity = 2
ids = ["a", "b"]
quantity.times do
puts "outer loop"
ids.each_with_index do |id, index|
puts "inner loop"
# a bunch of nested if/thens
if index == 0
puts "do something else"
puts "send termination email"
break
end
end
end
The output was:
outer loop
inner loop
do something else
send termination email
outer loop
inner loop
do something else
send termination email
if I take out the break, the output changes to:
outer loop
inner loop
do something else
send termination email
inner loop
outer loop
inner loop
do something else
send termination email
inner loop
This effectively saves a few inner loop iterations. Is this what your are looking for?
Related Topics
Restarting a Loop from the Top
How to Check If a Value Exists in an Array in Ruby
How to Match the Last Occurrence of a Pattern
How to Install a Gem or Update Rubygems If It Fails With a Permissions Error
Error: While Executing Gem ... (Gem::Filepermissionerror)
Rails Activerecord Perform Group, Sum and Count in One Query
How to Calculate Number of Chars Common to Two Strings
Why Is It Bad Style to 'Rescue Exception =≫ E' in Ruby
How to Call Shell Commands from Ruby
Why Is "Slurping" a File Not a Good Practice
How to Remove Rvm (Ruby Version Manager) from My System
How to Use the Conditional Operator (? :) in Ruby
Ssl Error When Installing Rubygems, Unable to Pull Data from 'Https://Rubygems.Org/
Installed Ruby 1.9.3 With Rvm But Command Line Doesn't Show Ruby -V