Ruby中的redo和retry语句有什么作用?

7
我想到redo唯一的用途可能是用于像写入socket或从数据库读取等操作,但如果这些操作失败一次,随后的尝试很可能也会失败,所以对我来说它仍然有点没有意义。至于retry,我真的想不出任何有用的情况。
这可能只是对我来说毫无意义,因为我不知道也不使用Ruby,但我渴望有一天能创建一个很棒的语言,所以我想至少了解一下最受欢迎的语言之一的设计背后的原因。

1
你所断言的“后续尝试很可能也会失败”似乎存在争议。在我看来,这取决于失败的原因和情况。例如,如果你的数据库操作文件死锁是由于其他人正在运行的查询引起的,那么退后并重试就是完全正确的做法。 - Frederick Cheung
2个回答

9
这个想法是在调用redoretry之前更改某些内容,希望第二次尝试时可以成功。我没有redo的例子,但我们在我正在工作的应用程序中发现了retry的用途。基本上,如果你有一段代码可能由于某些外部原因(例如网络)而失败,但每次运行代码都执行前置条件检查会太昂贵,你可以在begin...rescue块中使用retry。不确定是否清楚,因此我将直接给出示例。
基本上,我们有一些使用Net:SFTP访问远程目录的代码。该目录应该存在,但在某些特殊情况下可能还没有创建。如果不存在,我们想尝试一次创建它。但是,每次执行网络访问以检查目录是否存在会太昂贵,特别是在极少数情况下才会不存在。因此,我们按以下方式执行:
tried_mkdir = false
begin
  # Attempt to access remote directory
  ...
rescue Net::SFTP::StatusException
  raise if tried_mkdir
  tried_mkdir = true
  # Attempt to make the remote directory
  ...
  retry
end

7
< p > "redo" 的使用场景可以是用户输入检查:< /p >
nums = Array.new(5){[rand(1..9), rand(1..9)]}
nums.each do |num1, num2|
  print "What is #{num1} + #{num2}: "
  redo unless gets.to_i == num1 + num2
end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接