2010-03-28 24 views
33

Tôi có một nhiệm vụ Rake mà tôi đã đơn giản hóa dưới đây. Tôi đang sử dụng Ruby 1.9 trên Windows.Tại sao Rake không thể gọi nhiều tác vụ liên tiếp?

Có lẽ bạn muốn đoán kết quả của việc gọi tác vụ Rake "list_all_levels" bên dưới? Nó phải là:

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

Nhưng vì lý do nào đó, tôi chỉ in "Hello level 1" rồi dừng.

Tức là, nó luôn luôn chỉ gọi nhiệm vụ đầu tiên. Nếu tôi thay đổi dòng đầu tiên để vượt qua arg "42", nó sẽ in "Xin chào cấp 42" và sau đó dừng lại.

Tôi tự hỏi tại sao nó không gọi nhiệm vụ 3 lần và in tất cả 3 dòng? Và có cách nào để làm cho nó hoạt động như thế nào tôi mong đợi?

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 

Trả lời

47

Vấn đề là invoke chỉ gọi nhiệm vụ nếu nó là cần thiết . Chạy rake --trace cho thấy:

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

Vì vậy, bạn có thể thấy nó đang cố gắng để gọi nhiệm vụ :list hơn hai lần. Nhưng có một điều bạn có thể làm là thay đổi cơ thể của nhiệm vụ chính:

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 

sau đó nhiệm vụ :list là cần thiết nữa và nó một cách chính xác in ra tất cả 3 báo cáo.

Cách sạch hơn để làm điều đó là để 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 

Đó thay đổi tuyên bố puts bạn để sử dụng chỉ args hơn args.level đối với một số lý do. Có một số cảnh báo khác khi sử dụng execute trên invoke được mô tả trong liên kết ở trên.

+0

Điều này thực sự đã cứu ngày của tôi, cảm ơn! – kizzx2

+2

Hãy cẩn thận nếu thay đổi nó thành 'execute' @PandaWood vì chúng không giống chính xác => [rake execute vs invoke] (http://chrisroos.co.uk/blog/2007-12-06-ruby-rake -invoke-vs-execute) – Ron

+0

Điều này có vẻ rất trực quan đối với tôi. Bất kỳ ý tưởng nào tại sao họ làm như thế này? – marcovtwout

6

Bạn cần bật lại tác vụ trước khi thực thi mới, vì điều này, bạn chỉ cần thực thi phương thức có thể kích hoạt lại. Giống như người dùng Mark Rushakoff đã đề cập.

Rake::Task[:list].reenable 
Các vấn đề liên quan