重试语句如何在Ruby起作用



我才刚刚开始在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

redoretry工作值得读取的工作有一些重大变化。

IMHO,使用loop击败了给定练习的目标,因此我使用redoretry还有另外两个解决方案,并且我不想共享的循环。

如果您不知道我是怎么做到的,我建议您在查看解决方案之前先尝试。

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

最新更新