2010-03-28 2 views
33

У меня есть задача Rake, которую я упростил ниже. Я использую Ruby 1.9 для Windows.Почему Rake не может последовательно вызывать несколько задач?

Возможно, вы хотели бы угадать результат вызова задачи Rake «list_all_levels» ниже? Оно должно быть:

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

Но по неизвестным причинам для меня, он печатает только «Hello уровень 1», а затем останавливается.

То есть, он всегда вызывает только первую задачу. Если я изменил первую строку, чтобы передать аргумент «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

+2

Будьте осторожны, если вы меняете его на 'execute' @PandaWood, поскольку они не совсем одинаковы => [rake execute vs invoke] (http://chrisroos.co.uk/blog/2007-12-06-ruby-rake -invoke-vs-execute) – Ron

+0

Это кажется мне очень интуитивно понятным. Любые идеи, почему они сделали это так? – marcovtwout

6

Вам нужно снова включить задачу перед новым исполнением, для этого вам просто нужно выполнить способ, который можно использовать повторно. Как сказал Марк Рушаков.

Rake::Task[:list].reenable 
Смежные вопросы