平时如果跟Rake Task有过接触的同学都会知道,当我们需要在一个Task里边调用另一个Task的时候,我们可以使用Rake::Task['task_name'].invoke
的方式。但是在今天的实践中,才知道Rake::Task#invoke
在默认情况下在整个运行过程中将只会被调用一次而已。话不多说,动手演示:
准备一个say hello的task,代码:
# lib/tasks/demo.rake
namespace :demo do
desc "Print 'Hello' string"
task :say_hello do
puts "Hello, World!"
end
end
接下来在命令行中执行rake task:
$ rake demo:say_hello
=> Hello, World!
假设我们一个循环,需要调用上边的task共5次,那么我们可能会这么写:
namespace :demo do
# ....
desc "Print 'Hello, World!' five times"
task :say_five_hello do
5.times do
Rake::Task['demo:say_hello'].invoke
end
end
end
Ok, 让我们尝试着运行这个say_five_hello
的task,是不是真的会打印5次’Hello, World!’呢?
$ rake demo:say_five_hello
=> Hello, World!
结果就是,’Hello, World!’只打印了一次,也就是说,我们的Rake::Task['demo:say_hello']
只被运行了一次。
经过搜索,从StackOverflow找到了这个问题的相关描述,详见:How do I execute Rake tasks with arguments multiple times?
按照答案中的描述,我们有两种修改方案。第一种就是将上述代码进行修改:
namespace :demo do
# ...
desc "Print 'Hello, World!' five times"
task :say_five_hello do
5.times do
Rake::Task['demo:say_hello'].execute
end
end
end
再次运行,这次总算得到期待结果了:
$ rake demo:say_five_hello
=> Hello, World!
Hello, World!
Hello, World!
Hello, World!
Hello, World!
而第二种方法则会稍微麻烦一点:
namespace :demo do
# ...
desc "Print 'Hello, World!' five times"
task :say_five_hello do
5.times do
Rake::Task['demo:say_hello'].reenable
Rake::Task['demo:say_hello'].invoke
end
end
end
再次执行rake task, 同样能够得到预期结果:
$ rake demo:say_five_hello
=> Hello, World!
Hello, World!
Hello, World!
Hello, World!
Hello, World!
未完待续
针对重复调用的行为上的不同只是invoke
以及execute
方法之间的一个基本差异而已,那第一种方案跟第二种方案的差异又有什么不同?在带参数的情况下,又该如何考虑两个方法之间的差异?