假设以下的 Ruby 代码:
bank.branches do |branch|
branch.employees.each do |employee|
NEXT BRANCH if employee.name = "John Doe"
end
end
NEXT BRANCH 当然是伪代码。有没有一种方法可以像Perl中那样(通过使用循环标签)跳出父循环?
提前感谢。
假设以下的 Ruby 代码:
bank.branches do |branch|
branch.employees.each do |employee|
NEXT BRANCH if employee.name = "John Doe"
end
end
NEXT BRANCH 当然是伪代码。有没有一种方法可以像Perl中那样(通过使用循环标签)跳出父循环?
提前感谢。
catch和throw可能是你正在寻找的:
bank.branches do |branch|
catch :missingyear do #:missingyear acts as a label
branch.employees.each do |employee|
(2000..2011).each do |year|
throw :missingyear unless something #break out of two loops
end
end
end #You end up here if :missingyear is thrown
end
catch
和 throw
并不是用于错误处理。Ruby 使用 raise
和 rescue
来处理错误。catch
和 throw
主要是为了跳出一个上下文环境。就像其他一些语言中的 goto
一样。 - Gurpartap Singh没有内置的方法可以在不得到容器块许可的情况下跳出其中。你只能像这样做:
bank.branches do |branch|
break unless branch.employees.each do |employee|
break if employee.name == "John Doe"
end
end
while c1
while c2
# execute code
do_break = true if need_to_break_out_of_parent_loop
end
break if do_break
end
我的想法是将嵌套块移动到一个方法中,用return
代替break
。
def find_branch_and_employee_by_name(bank,emp_name)
bank.branches.each do |branch|
branch.employees.each do |employee|
return([branch,employee]) if employee.name == emp_name
end
end
nil # employee wasn't found
end
def workforce
bank.branches do |branch|
switch = 0
branch.employees.each do |employee|
if switch == 1
next
end
if employee.name = "John Doe"
switch = 1
end
end
end
在开关被切换后,内部数组将不再处于活动状态,并且父循环将移动到下一个分支并重置开关。显然,可以使用更多的开关来处理更复杂的情况。
编辑: 结果发现,可以通过在内部循环中调用break(仅终止该循环)来更简单地实现所需的效果:
bank.branches do |branch|
branch.employees.each do |employee|
break if employee.name = "John Doe"
end
end
这是使用 Ruby 的 begin-rescue-end 块编写的 @steenslag 想表达的意思:
letters = [%w(a b c),%w(d e f),%w(g h i)]
# => [["a", "b", "c"], ["d", "e", "f"], ["g", "h", "i"]]
letters.each do |trine|
begin
trine.each do |letter|
raise "Breaking out of inner cycle." if letter == "e"
puts letter
end
rescue
next
end
end
# => abcdghi
所以你的例子是:
bank.branches do |branch|
branch.employees.each do |employee|
begin
raise "Breaking out of inner cycle." if employee.name = "John Doe"
rescue
next
end
end
end