如何从抽佣任务中早日返回?


226

我有一个rake任务,在开始时要进行一些检查,如果其中一项检查失败,我想从rake任务中早返回,则我不想执行任何剩余的代码。

我认为解决方案是将返回值放到我想从代码中返回的位置,但是出现以下错误

unexpected return

Answers:


285

Rake任务基本上是一个块。除了lambdas以外,一个块不支持return,但是您可以跳到下一个语句next,在rake任务中使用该语句具有与在方法中使用return相同的效果。

task :foo do
  puts "printed"
  next
  puts "never printed"
end

或者,您可以在方法中移动代码并在方法中使用return。

task :foo do
  do_something
end

def do_something
  puts "startd"
  return
  puts "end"
end

我更喜欢第二选择。


18
我也最喜欢第二个。我使用rake的次数越多,我越喜欢将非平凡的代码保留在任务定义之外。这不是一个100%坚定的规则,但似乎是工作的良好指南。
Mike Woodhouse,2010年

6
我尝试过break,但遇到了这个错误:耙子中止了!从proc-closure中断(通过使用--trace运行任务查看完整的跟踪信息)
pupeno 2010年

4
我更喜欢使用next。为什么我们要声明一种新方法只是为了支持早期回报?
Derek Greer

5
如果您嵌套在多个块​​中,该怎么办?(next仅在要突破的“级别”上有效
。– mjs

3
警告:在Rake任务中声明方法不是一个好主意,因为它们对于所有已加载的Rake任务都是全局的,与名称空间无关。使用next而不是break,因为执行该块的任何内容都可以多次调用该块中的代码(请考虑.each方法)。
Leslie Viljoen


22

abort在这种情况下,我倾向于使用哪种更好的选择,例如:

task :foo do
  something = false
  abort 'Failed to proceed' unless something
end

1
但是如何在abort不退出1代码的情况下退出呢?Rake任务通常在命令行中用于确定成功或失败。是否有“成功的” abort
约书亚·品特

2
回答了我自己的问题:看起来exit是成功退出的好方法。
约书亚·品特

19

返回错误Error

如果你正在返回错误(即退出代码1),你要使用abort,这也需要一个可选的字符串PARAM,将获得在退出输出:

task :check do

  # If any of your checks fail, you can exit early like this.
  abort( "One of the checks has failed!" ) if check_failed?

end

在命令行上:

$ rake check && echo "All good"
#=> One of the checks has failed!

成功回报✅

如果您返回的消息没有错误(例如,退出代码为0),则需要使用exit,它不会使用字符串参数。

task :check do

  # If any of your checks fail, you can exit early like this.
  exit if check_failed?

end

在命令行上:

$ rake check && echo "All good"
#=> All good

如果您要在cron作业中使用此功能,或者根据rake任务是否成功而需要在事后执行某些操作,则这一点很重要。



8

如果您要退出耙任务而不会导致“耙中止!” 要打印的消息,则可以使用“中止”或“退出”。但是,“中止”在救援块中使用时,会终止任务并打印整个错误(即使不使用--trace)。所以“退出”是我使用的。


3
通常,我认为使用“退出”而不是返回/中断是一个坏主意,因为它不仅会跳出当前的 proc / method / etc。-它退出了整个过程,并跳过了调用方方法之后可能要运行的任何代码(包括可能的一些清除)。但是对于耙任务,我想这可能不是问题……
泰勒·里克

0

我使用next了Simone Carletti建议的方法,因为在测试rake任务时,abort实际上这只是一个包装。exit,这并不是期望的行为。

例:

task auto_invoice: :environment do
  if Application.feature_disabled?(:auto_invoice)
    $stderr.puts 'Feature is disabled, aborting.'
  next
end
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.