2010-03-28 13 views
33

Tengo una tarea de Rake que he simplificado a continuación. Estoy usando Ruby 1.9 en Windows.¿Por qué Rake no puede invocar múltiples tareas consecutivamente?

Quizás le gustaría adivinar el resultado de llamar a la tarea de Rake "list_all_levels" a continuación? Debe ser:

"Hello level 1" 
"Hello level 2" 
"Hello level 3" 

Pero por razones desconocidas para mí, se imprime sólo "Hola nivel 1" y luego se detiene.

Es decir, siempre invoca solo la primera tarea. Si cambio la primera línea para pasar el arg "42", se imprimirá "Hola nivel 42" y luego se detendrá.

Me pregunto por qué no invocar la tarea 3 veces e imprimir las 3 líneas? ¿Y hay alguna manera de hacer que funcione como yo esperaría?

task :list_all_levels => [] do 
    Rake::Task[:list].invoke 1 
    Rake::Task[:list].invoke 2 
    Rake::Task[:list].invoke 3 
end 

task :list, [:level] => [] do |t, args| 
    puts "Hello level #{args.level}" 
end 

Respuesta

47

El problema es que sólo se invoca invoke la tarea si es necesario . Correr rake --trace muestra:

 
(in /tmp/ruby) 
** Invoke default (first_time) 
** Execute default 
** Invoke list (first_time) 
** Execute list 
Hello level 1 
** Invoke list 
** Invoke list 

Así se puede ver que está tratando de invocar la tarea :list dos veces más. Pero una cosa que puede hacer es cambiar el cuerpo de la tarea principal a:

task :default => [] do 
    Rake::Task[:list].invoke 1 
    Rake::Task[:list].reenable 
    Rake::Task[:list].invoke 2 
    Rake::Task[:list].reenable 
    Rake::Task[:list].invoke 3 
end 

entonces la tarea :list se necesita de nuevo y se imprime correctamente los 3 estados.

La forma más limpia de hacerlo es use execute rather than invoke:

task :default => [] do 
    Rake::Task[:list].execute 1 
    Rake::Task[:list].execute 2 
    Rake::Task[:list].execute 3 
end 

task :list, [:level] => [] do |t, args| 
    puts "Hello level #{args}" 
end 

Eso cambia su estado de puts utilizar simplemente args en lugar de args.level por alguna razón. Hay algunas otras advertencias con el uso de execute sobre invoke descrito en el enlace de arriba.

+0

Esto realmente me salvó la vida, gracias! – kizzx2

+2

Tenga cuidado con si lo cambia a 'execute' @PandaWood ya que no son exactamente iguales => [rake execute vs invoke] (http://chrisroos.co.uk/blog/2007-12-06-ruby-rake -invoke-vs-execute) – Ron

+0

Esto me parece muy contrario a la intuición. ¿Alguna idea de por qué lo hicieron así? – marcovtwout

6

Necesita volver a habilitar la tarea antes de la nueva ejecución, para esto, solo necesita ejecutar el método reactivable. Como el usuario Mark Rushakoff mencionado.

Rake::Task[:list].reenable 
Cuestiones relacionadas