Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails ruby:在发生异常后在同一循环迭代中继续_Ruby On Rails_Ruby - Fatal编程技术网

Ruby on rails ruby:在发生异常后在同一循环迭代中继续

Ruby on rails ruby:在发生异常后在同一循环迭代中继续,ruby-on-rails,ruby,Ruby On Rails,Ruby,我觉得有点奇怪,因为有很多问题有点像这样,但距离不够近,或者没有答案 [编辑:我正在重新表述问题,以使其更清楚] 我有一个循环,它可以做很多事情,我在玩它,看看各种选项是否可以使事情更可读、更清晰。最后,我搞砸了一些东西,它抛出了一个异常,这被救援人员抓住了。到现在为止,一直都还不错。然而,我找不到任何方法让ruby在循环的同一个迭代中继续执行以下语句——异常总是导致以下语句,并继续执行下一个迭代——默认行为。重做或重试将毫无意义,并导致无限循环,再次遇到相同的错误和异常,等等 我想知道有没有办

我觉得有点奇怪,因为有很多问题有点像这样,但距离不够近,或者没有答案

[编辑:我正在重新表述问题,以使其更清楚]

我有一个循环,它可以做很多事情,我在玩它,看看各种选项是否可以使事情更可读、更清晰。最后,我搞砸了一些东西,它抛出了一个异常,这被救援人员抓住了。到现在为止,一直都还不错。然而,我找不到任何方法让ruby在循环的同一个迭代中继续执行以下语句——异常总是导致以下语句,并继续执行下一个迭代——默认行为。重做或重试将毫无意义,并导致无限循环,再次遇到相同的错误和异常,等等

我想知道有没有办法强迫ruby以某种方式处理错误,然后继续它停止的地方

这是一个样本,从我不知道的地方偷来的

3.times do |i|
  begin
    # first bunch of stuff to do
    # second bunch of stuff to do
    # third bunch of stuff to do
    # fourth bunch of stuff to do
  rescue => e
    p e
  end
end
基本上,在本例中,我希望在继续循环的下一次迭代之前执行所有四组内容,即使其中一个会导致错误。我没有处理错误,允许我看到异常结果,等等,但实际上忽略了它,继续做所有其他的事情


有什么想法吗?这可能是我以前从未见过的非常明显的东西。

一个
开始
块(包括say
def
中的隐式块)在第一个异常处结束。如果你想在做完某件事后,不管成败,都要分开做,那么就把它放在块外

3.times do |i|
  begin
    raise "Raised from iteration #{i}"
  rescue => e
    p e
  end
  puts "I'm after the exception"
end
如果您想在
返回
中断
等之后执行某项操作,请使用
确保

5.times do |i|
  begin
    break if i == 3
    raise "Raised from iteration #{i}"
  rescue => e
    p e
  ensure
    puts "I always run #{i}"
  end
end
哪些产出:

#<RuntimeError: Raised from iteration 0>
I always run 0
#<RuntimeError: Raised from iteration 1>
I always run 1
#<RuntimeError: Raised from iteration 2>
I always run 2
I always run 3
产出:

Supressing I throw sometimes 0
After possible exceptions 0
Supressing I throw sometimes 1
After possible exceptions 1
Supressing I throw sometimes 2
After possible exceptions 2
Supressing I throw sometimes 3
Supressing I throw sometimes too 3
After possible exceptions 3
Supressing I throw sometimes too 4
After possible exceptions 4

您正在使用
rescue
子句定义
begin-end
块。如果块引发任何异常,并且存在匹配的rescue子句,则块将停止执行,rescue子句将被执行。如果没有匹配的rescue块,错误将冒泡(希望由另一个块处理,否则将不处理,脚本将停止!)如果有
sure
子句,即使出现异常,也会运行该子句

那我们该怎么办?如果您想防御单个步骤的失败并继续执行,则每个步骤都需要自己的块:

3.times do |i|
  begin
    first_thing
  rescue => e
    puts "The first thing blew up! #{e.inspect}"
    puts "I'll carry on anyway ¯\\_(ツ)_/¯"
  end

  begin
    second_thing
    third_thing
  rescue => e
    puts "Either the second or third thing blew up... #{e.inspect}"
    puts "Straight on to the fourth thing!"
  end

  begin
    fourth_thing
  rescue => e
    puts "Fourth thing blew up! #{e.inspect}"
  end
end


有这样一个块是有点不寻常的,如果出现问题,它应该继续执行——这通常也是使下一个步骤出错的好方法!您可能需要确保在每个点上仍然具有数据完整性,并且后面的步骤不依赖于在前面的步骤中可能失败的某些事情。

是否应该执行
puts
,而不管是否发生异常?是。这模拟了我正在处理的主程序中的字符串操作等。如果你在流控制中使用故意的异常,那可能是错误的。为什么不只是一个
if
?顺便说一句,谢谢您的编辑-您编辑它时,我刚刚添加了“”“我有一个循环可以做很多事情”——也许你应该提供一个更详细的例子。很难根据循环中的单个
开始救援
块给出建议:-)感谢Fire Lancer-但如果您知道某段代码可能会通过并出现异常,那么这是可行的。如果您不知道,或者不知道是哪一部分,那么您希望援救工作能够围绕所有代码展开,因此您不必这样做。想象一下,加薪实际上是一堆东西,在某些情况下,可能会抛出异常。一般来说,在异常之后继续“下一个语句”是不安全的,而且会很困难,如果你真的想,你需要以某种方式显式地包装它们,或者分开显式开始块,或者是一些包装方法,你不想写推过异常并继续运行的YOLO代码。注意,由于这是用ruby on rails标记的,所以ActiveSupport为你添加了一个方法,假设你没有从itThanks all得到
put
语句,那么我想我有我的答案了。实际上,没有什么内置的方法来处理错误,然后继续。如果我想这样做,分开的街区是最好的选择。这有点笨重,但你很少能得到生活中的一切!这里的基础是从一个文件中读取一行,在检查网络是否正常后,文件是否存在并可以打开,我们实际上得到了一行,然后对它/用它做了大量独立的事情,因此我对它感到满意,直到出现这种错误和情况,这让我在花了一天时间在非工作解决方案上之后走上了这条道路
3.times do |i|
  begin
    first_thing
  rescue => e
    puts "The first thing blew up! #{e.inspect}"
    puts "I'll carry on anyway ¯\\_(ツ)_/¯"
  end

  begin
    second_thing
    third_thing
  rescue => e
    puts "Either the second or third thing blew up... #{e.inspect}"
    puts "Straight on to the fourth thing!"
  end

  begin
    fourth_thing
  rescue => e
    puts "Fourth thing blew up! #{e.inspect}"
  end
end