Ruby 中的重试语句如何工作?
How does the retry statement work in Ruby?
我才刚刚开始使用 Ruby,但我所遵循的手册似乎已经过时了。我一直在做一些研究,但一直找不到明确的答案。
手册在一个应该作为循环的方法中使用了 'retry' 关键字,但它没有使用 begin/rescue 块,当你强制 'retry' 关键字位于 begin/rescue 块内。
我试过很多东西:
- 第一个是在方法的开头使用 "begin" 关键字,在重试点使用 'raise',然后是相应的 'rescue; retry; end;'。
-最后一个是在外面使用'begin/rescue'块,包装方法的调用。
按照手册中的逻辑,只有最后一个可以正常工作。
有一些例子:
手册中的代码如下:
def WHILE(cond)
return if not cond
yield
retry
end
i=0; WHILE(i<3) {print i; i+=1}
结果:
012
我试过以下方法:
def WHILE(cond)
begin
return if not cond
yield
raise
rescue
retry
end
end
i=0; WHILE(i<3) {print i; i+=1}
结果:
无穷大
def WHILE(cond)
return if not cond
yield
end
i=0; begin; WHILE(i<3) {print i; i+=1}; raise; rescue; retry; end
结果:
012 (加上一个明显的无限循环什么都不打印)
我希望你能让我摆脱这种存在主义的怀疑,但这是我的结论。
在 'retry' 关键字必须使用 begin/rescue 块之前,它可能会以无法再使用的方式使用,重复调用 的方法,尽管 在该方法内部 。
现在,它只是跳转到 'begin' 语句。
但我不确定这一点,我需要确认。如果是这样,是否有任何形式可以恢复这种使用?
谢谢。
您的 WHILE
的行为与常规 while
不同,因为在您的情况下 i<3
在调用时 计算一次 。 while
语句每次都对其求值。
如果你想写一个 while
等价物,重要的是你的条件是 可以 评估的,而不是 已经评价。
您可以通过接受 Proc 作为条件来解决这个问题:
def so_long_as(cond)
loop do
return unless cond.call
yield
end
end
然后你这样称呼它:
i = 0
so_long_as(-> { i < 3 }) do
print i
i += 1
end
现在打印 012
并正确终止。
需要注意的重要一点是 retry
仅在 begin
/end
上下文中起作用,而不是常规方法,现在您必须使用 redo
:
i = 0
redone = false
so_long_as(-> { i < 3 }) do
print i
unless (redone)
redone = true
redo
end
i += 1
end
现在打印 0012
的地方。
恕我直言,使用 loop
有点违背给定练习的目标,因此我有两个其他解决方案使用 redo
或 retry
并且没有我想要的循环分享。
如果您不知道我是怎么做到的,我建议您在查看解决方案之前尝试一下。
1。 retry
def _while(cond, _loop=Class.new(RuntimeError))
raise _loop if cond.call
rescue _loop
yield
retry
end
i = 0
_while(-> { i < 3 }) do
print i
i += 1
end
2。 redo
def _while(cond)
proc do
if cond.call
yield
redo
end
end.call
end
i = 0
_while(-> { i < 3 }) do
print i
i += 1
end
我才刚刚开始使用 Ruby,但我所遵循的手册似乎已经过时了。我一直在做一些研究,但一直找不到明确的答案。
手册在一个应该作为循环的方法中使用了 'retry' 关键字,但它没有使用 begin/rescue 块,当你强制 'retry' 关键字位于 begin/rescue 块内。
我试过很多东西: - 第一个是在方法的开头使用 "begin" 关键字,在重试点使用 'raise',然后是相应的 'rescue; retry; end;'。 -最后一个是在外面使用'begin/rescue'块,包装方法的调用。
按照手册中的逻辑,只有最后一个可以正常工作。
有一些例子:
手册中的代码如下:
def WHILE(cond)
return if not cond
yield
retry
end
i=0; WHILE(i<3) {print i; i+=1}
结果: 012
我试过以下方法:
def WHILE(cond)
begin
return if not cond
yield
raise
rescue
retry
end
end
i=0; WHILE(i<3) {print i; i+=1}
结果: 无穷大
def WHILE(cond)
return if not cond
yield
end
i=0; begin; WHILE(i<3) {print i; i+=1}; raise; rescue; retry; end
结果: 012 (加上一个明显的无限循环什么都不打印)
我希望你能让我摆脱这种存在主义的怀疑,但这是我的结论。
在 'retry' 关键字必须使用 begin/rescue 块之前,它可能会以无法再使用的方式使用,重复调用 的方法,尽管 在该方法内部 。
现在,它只是跳转到 'begin' 语句。
但我不确定这一点,我需要确认。如果是这样,是否有任何形式可以恢复这种使用?
谢谢。
您的 WHILE
的行为与常规 while
不同,因为在您的情况下 i<3
在调用时 计算一次 。 while
语句每次都对其求值。
如果你想写一个 while
等价物,重要的是你的条件是 可以 评估的,而不是 已经评价。
您可以通过接受 Proc 作为条件来解决这个问题:
def so_long_as(cond)
loop do
return unless cond.call
yield
end
end
然后你这样称呼它:
i = 0
so_long_as(-> { i < 3 }) do
print i
i += 1
end
现在打印 012
并正确终止。
需要注意的重要一点是 retry
仅在 begin
/end
上下文中起作用,而不是常规方法,现在您必须使用 redo
:
i = 0
redone = false
so_long_as(-> { i < 3 }) do
print i
unless (redone)
redone = true
redo
end
i += 1
end
现在打印 0012
的地方。
恕我直言,使用 loop
有点违背给定练习的目标,因此我有两个其他解决方案使用 redo
或 retry
并且没有我想要的循环分享。
如果您不知道我是怎么做到的,我建议您在查看解决方案之前尝试一下。
1。 retry
def _while(cond, _loop=Class.new(RuntimeError))
raise _loop if cond.call
rescue _loop
yield
retry
end
i = 0
_while(-> { i < 3 }) do
print i
i += 1
end
2。 redo
def _while(cond)
proc do
if cond.call
yield
redo
end
end.call
end
i = 0
_while(-> { i < 3 }) do
print i
i += 1
end