2010-03-28 75 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