2010-03-28 71 views
33

我有一個Rake任務,我在下面進行了簡化。 我在Windows上使用Ruby 1.9。爲什麼Rake無法連續調用多個任務?

也許你想猜測下面調用Rake任務「list_all_levels」的結果嗎?它應該是:

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

但由於我不知道的原因,它只打印「你好級別1」,然後停止。

也就是說,它總是隻調用第一個任務。 如果我更改第一行以傳遞arg「42」,它會打印出「Hello level 42」,然後停止。

我想知道爲什麼它不是調用任務3次並打印所有3行? 有什麼辦法讓它工作我期望的?

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 

回答

47

的問題是,invoke只調用任務,如果它是需要。運行rake --trace顯示:

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

所以你可以看到它試圖:list兩次調用任務。但有一兩件事你可以做的是改變的主要任務身體:

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 

然後再次需要:list任務,它正確地打印出所有3個語句。

的更清潔的方式來做到這一點是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 

這改變你的puts聲明只使用args而不是args.level出於某種原因。使用execute而不是上述鏈接中描述的invoke還有一些其他注意事項。

+0

這真的救了我一天,謝謝! – kizzx2 2010-07-09 20:27:35

+2

如果將它更改爲'execute' @PandaWood,請注意,因爲它們不完全相同=> [rake execute vs invoke](http://chrisroos.co.uk/blog/2007-12-06-ruby-rake -invoke-vs-execute) – Ron 2014-08-29 15:49:43

+0

這對我來說似乎非常不直觀。任何想法,他們爲什麼這樣做? – marcovtwout 2016-01-29 16:26:06

6

您需要在新執行前重新啓用任務,爲此,您只需執行重新啓用的方法。就像用戶Mark Rushakoff所說的那樣。

Rake::Task[:list].reenable