FM牛鍵屋本舗

プログラマ(弱)の日々精進系ブログ

Rakeではファイルすべてがまず評価されるよ!!

またまたパーフェクトRubyから。

Rakeのファイルタスクの説明でわからない部分があり、 ここ3日くらい頭を抱えたり鼻歌を歌ったりしていたんですが、 ようやく理解出来たので、記録として残しておきます。 願わくば同じ悩みを抱えている人を救えますように。いないか。

Rakefile上でファイルタスクを使うと、ファイルが存在しない場合の処理が記載できます。

file ファイル名 do |file_name|
  # ファイルを作るなりなんなり好きにすればいいさ!
end

もし、ファイル名に指定したものが存在している場合は実行されません。

さて、そんなファイルタスクの説明は、その前項での「ファイルが存在していない場合はエラーとして処理終了」なサンプルを改良するという形式をとっていました。

自分なりに消化して書くと、以下のような感じに。

TEXT_FILES = [
  'file1.txt',
  'file2.txt',
  'file3.txt
]

task :check => TEXT_FILES do
end

TEXT_FILES.each do |file_name|
  file file_name do
    sh "touch #{file_name}"
  end
end

僕は

TEXT_FILESなんてタスクないじゃん!! なんで動くのこれ!?

なんて思ってました恥ずかしい。

どうもいろんなところにputs仕込んで確認すると、 個別のタスクが実行される前に、 Rakefile全体がまず評価されることがわかりました。

そのため、

  1. :checkが評価される
  2. 依存しているTEXT_FILESはどこ…??
  3. TEXT_FILES.eachが何故か評価される

ではなく

  1. ファイルの全量が読まれTEXT_FILES.eachにより、配列要素すべてのfileタスクが定義される
    ※この際、タスク名はファイル名となる
  2. :checkが実行される
  3. 依存しているタスク名の配列(=ファイル名)の配列が順番に実行される

ということになるようです。 当たり前だけど、逐次実行ではないんだなあ。