VTRyo Blog

一歩ずつ前に進むブログ

rake taskでループ内にあるinvokeが実行されない

rake taskのinvoke

こういうパターンのrake taskがあったとする

ids = [1,2,3]

ids.find_each do |id| 
  Rake::Task['sync_documents'].invoke(id)
  p === execute id ===
end

これを実行すると execute 1までしか実行されずに困ったという話。

reenableが必要

結論から言えばこう。

ids = [1,2,3]

ids.find_each do |id| 
  Rake::Task['sync_documents'].invoke(id)
  Rake::Task['sync_documents'].reenable
  p === execute id ===
end

何故

どうやら一度実行したinvokeには、already_invokedというフラグが立つようだ。

www.rubydoc.info

リファレンスにはこうある。

invoke / 呼び出し

あるタスクが呼び出されると、最初にそのタスクが以前呼び出されたことがあるかチェックします。呼び出されたことがあれば何もしません。そのタスクが初めて呼び出された場合は、そのタスクの事前タスクを一つずつ呼び出します。最終的に、このタスクのアクションを実行する必要があるかどうかチェックします。このタスクを実行する必要があれば、アクションを実行します。 NOTE: このタスクを実行する必要が無い場合も事前タスクは呼び出されています。この振る舞いは将来変更予定です。

docs.ruby-lang.org

なるほど。

あとはソースを読むともっとよくわかる。

github.com

github.com

感想

ドキュメントを読むのも良いが、最近はソースまで読む癖がついてきたので理解までの時間がぐっと短くなった気がする。

ブログには他の困ってる人がいたらと残すことがあるけど、 「これ書かなくてもソース読んだらわかるな…」って思うようになってしまったのが自分の中で成長でもあり寂しい部分でもある。

ちなみに今回は探すのが大変だったのでブログにした。誰かの参考になれば嬉し。