2010-03-28 2 views
33

J'ai une tâche Rake que j'ai simplifiée ci-dessous. J'utilise Ruby 1.9 sous Windows.Pourquoi Rake ne peut pas invoquer plusieurs tâches de manière consécutive?

Vous voudriez peut-être deviner le résultat de l'appel de la tâche Rake "list_all_levels" ci-dessous? Il devrait être:

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

Mais pour des raisons inconnues me, il imprime seulement « Bonjour niveau 1 », puis arrête.

En d'autres termes, il invoque toujours uniquement la première tâche. Si je change la première ligne pour passer l'argument "42", il affichera "Bonjour niveau 42" puis s'arrêtera.

Je me demande pourquoi pas invoquer la tâche 3 fois et imprimer les 3 lignes? Et y a-t-il un moyen de le faire fonctionner comme je m'y attendais?

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 

Répondre

47

Le problème est que invoke invoque la tâche que si elle est nécessaire . L'exécution rake --trace montre:

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

vous pouvez donc voir qu'il essaie d'invoquer la tâche :list deux fois. Mais une chose que vous pouvez faire est de changer le corps de la tâche principale:

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 

alors la tâche :list est nécessaire à nouveau et il imprime correctement toutes les 3 déclarations.

La façon plus propre de le faire est de 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 

Cela change votre déclaration puts à utiliser juste args plutôt que args.level pour une raison quelconque. Il existe d'autres mises en garde avec l'utilisation execute sur invoke décrit dans le lien ci-dessus.

+0

Cela a vraiment sauvé ma journée, merci! – kizzx2

+2

Soyez prudent si vous le changez en 'execute' @PandaWood car ils ne sont pas exactement les mêmes => [rake execute vs invoke] (http://chrisroos.co.uk/blog/2007-12-06-ruby-rake -invoke-vs-execute) – Ron

+0

Cela semble très contre-intuitif pour moi. Des idées pourquoi ils l'ont fait comme ça? – marcovtwout

6

Vous devez réactiver la tâche avant la nouvelle exécution, pour cela, il vous suffit d'exécuter la méthode reenable. Comme l'a mentionné Mark Rushakoff.

Rake::Task[:list].reenable 
Questions connexes