我才刚刚开始在Ruby中开始,但是我遵循的手册似乎已经过时了。我一直在进行一些研究,但我一直找不到明确的答案。
手册使用了应该用作循环的方法内部的"重试"关键字,但是它在没有开始/救援块的情况下使用,当您强迫"重试"关键字进入内部时,这种行为似乎会大不相同
的开始/救援块我尝试了很多事情: - 第一个是在方法开始时使用"开始"的关键字,并在重试点上使用"加薪",然后是各自的"救援";重试;结尾;'。 - 最后一个是在外部使用"开始/救援"块,包裹了该方法的呼叫。
遵循手册中的逻辑,只有最后一个按原样运行。
有一些示例:
手册中的代码如下:
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 (加上明显的无限环路打印(
我希望您能摆脱这种存在的怀疑,但这是我的结论。
在"重试"关键字的"开始/救援块"强制使用之前,它可以以不再使用的方式使用,重复一种方法,尽管在该方法的内部。
现在,它只是跳到"开始"语句。
但我不确定,我需要确认。如果是这样,是否有任何形式可以恢复这种用途?
谢谢。
您的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
。
redo
和retry
工作值得读取的工作有一些重大变化。
IMHO,使用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