¿Cómo regreso temprano de una tarea de rastrillo?


226

Tengo una tarea de rastrillo donde hago algunas verificaciones al principio, si una de las verificaciones falla, me gustaría regresar temprano de la tarea de rastrillo, no quiero ejecutar ninguno de los códigos restantes.

Pensé que la solución sería colocar un retorno donde quería regresar del código, pero recibo el siguiente error

unexpected return

Respuestas:


285

Una tarea de rastrillo es básicamente un bloque. Un bloque, excepto lambdas, no admite el retorno, pero puede pasar a la siguiente instrucción nextque utiliza en una tarea de rastrillo el mismo efecto que usar el retorno en un método.

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

O puede mover el código en un método y usar return en el método.

task :foo do
  do_something
end

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

Prefiero la segunda opción.


18
También me gusta el segundo. Cuanto más uso el rastrillo, más me gusta mantener el código no trivial fuera de la definición de la tarea. No es una regla 100% firme, pero parece ser una buena guía para trabajar.
Mike Woodhouse

66
Lo he intentado breaky tengo este error: ¡rastrillo abortado! romper el proceso de cierre (Ver seguimiento completo ejecutando la tarea con --trace)
pupeno

44
Prefiero usar el siguiente. ¿Por qué deberíamos declarar un nuevo método solo para respaldar los retornos tempranos?
Derek Greer

55
¿Qué haces si estás profundamente anidado en varios bloques? ( nextsolo funciona si hay un "nivel" de bloque para salir.
mjs

3
Advertencia: declarar métodos en las tareas de Rake es una mala idea porque son globales para todas las tareas de Rake cargadas, sin importar el espacio de nombres. Luego se usa en lugar de break porque el código en el bloque puede ser llamado varias veces por lo que sea que esté ejecutando el bloque (piense en el método .each).
Leslie Viljoen

181

Puede usar abort(message)desde dentro de la tarea para anular esa tarea con un mensaje.


55
@TylerRick No, es Kernel # abort .
Jo Liss

10
Esta manera es superior para salir en situaciones sin éxito, ya que establece automáticamente el estado de salida.
samuil

Este es un ganador. También es una manera fácil de proporcionar comentarios de uso para errores de argumento.
David Hempy

En línea y mucho más explicativo que next. Quiéralo.
SomeSchmo

22

Tiendo a usar abortcuál es una mejor alternativa en tales situaciones, por ejemplo:

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

1
Pero, ¿cómo abortsin salir con un 1código de salida? Las tareas de rastrillo a menudo se usan en la línea de comando para determinar el éxito o el fracaso. ¿Hay un "exitoso" abort?
Joshua Pinter

2
Respondí mis propias preguntas: parece que exites una buena manera de salir con éxito.
Joshua Pinter

19

Regrese con un error ❌

Si regresa con un error (es decir, un código de salida de 1) que querrá usar abort, que también toma un parámetro de cadena opcional que se generará en la salida:

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

En la línea de comando:

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

Regrese con éxito ✅

Si regresa sin un error (es decir, un código de salida de 0), querrá usarlo exit, lo que no requiere un parámetro de cadena.

task :check do

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

end

En la línea de comando:

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

Esto es importante si está usando esto en un trabajo cron o algo que necesita hacer algo después en función de si la tarea de rake fue exitosa o no.



8

Si quisiste salir de una tarea de rastrillo sin causar el "rastrillo abortado". mensaje a imprimir, entonces puede usar "abortar" o "salir". Pero "abortar", cuando se usa en un bloque de rescate, finaliza la tarea e imprime todo el error (incluso sin usar --trace). Entonces "salir" es lo que uso.


3
En general, creo que usar "exit" en lugar de return / break es una mala idea, ya que no solo salta del proceso / método / etc actual . - sale de todo el proceso y omite cualquier código que el método de la persona que llama haya tenido la intención de ejecutar después (incluyendo posiblemente alguna limpieza). Pero para una tarea de rastrillo, supongo que probablemente no sea un problema ...
Tyler Rick

0

Utilicé el nextenfoque sugerido por Simone Carletti, ya que al probar la tarea de rastrillo abort, que de hecho es solo una envoltura exit, no es el comportamiento deseado.

Ejemplo:

task auto_invoice: :environment do
  if Application.feature_disabled?(:auto_invoice)
    $stderr.puts 'Feature is disabled, aborting.'
  next
end
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.