Ruby/Rakeに関する質問です。


以下のタスクの記述をRakefileにしたいと考えています
【1】入力ファイルが1つ用意されている。
【2】プログラム1を入力ファイルに対して用いて複数のファイルが生成される。
ファイル名形式はoutput.1, output.2, ... output.nというように決まっているが,
その数は処理1を行ってみるまでわからない。
【3】プログラム2をoutput.1, output.2, ... output.nの各ファイルに対して用いて,n個の出力ファイル群を得る。

この問題の解決には,Rakefileにおける依存関係の動的生成が必要だと思うのですが,いい方法を見つけることができません。アドバイスをお願いします!

回答の条件
  • 1人3回まで
  • 13歳以上
  • 登録:2011/01/10 09:58:21
  • 終了:2011/01/15 20:15:59

ベストアンサー

id:iwadon No.1

いわどん回答回数60ベストアンサー獲得回数132011/01/10 13:27:54

ポイント100pt
  1. Rakeのタスクは動的に定義可能。ただしそのままでは呼び出されないため自分で呼ぶ必要がある(違ってたらごめんなさい)。
  2. ルールもタスクと同様に動的定義が可能。

わざとらしい例で恐縮ですが、具体例を用意してみました。タスクやルールの動的定義・動的呼び出しのサンプルになれば幸いです。

# -*- Ruby -*-
task :default => [:rm_aN, :cp_a_aN]

task :rm_aN do
  rm Dir.glob('a[0-9]')
  touch 'a'
end

task :cp_a_aN do
  (rand(8) + 1).times do |i|
    cp 'a', ('a%d' % i)
  end
  rule(/b[0-9]/ => [proc{|t| t.sub(/^b/, 'a')}]) do |t|
    cp t.source, t.name
  end
  task :cp_aN_bN => Dir.glob('a[0-9]').map {|i| i.sub(/^a/, 'b')}
  Rake::Task[:cp_aN_bN].invoke
end

大まかには「ファイル a から a0, a1, ... aN を作成、さらに b0, b1, ... bN を作成する」という動作をします。

  1. まずタスク rm_aN でa0〜aNを削除しています。そして大元のファイル a を作成(すでに存在する場合は touch)しています。
  2. 次にタスク cp_a_aN の中でいくつかの処理を行っています。
    1. ファイル a を1〜9個にコピー。
    2. aN から bN を作るためのルールを定義。
    3. 動的にタスク cp_aN_bN を定義。
    4. 定義しただけではタスク cp_aN_bN は実行されないので自分で実行。先ほど定義したルールに則り b0, b1, ... bN が作成される。

試しに実行すると以下のように表示されます:

rm a0 a1
touch a
cp a a0
cp a a1
cp a a2
cp a a3
cp a a4
cp a a5
cp a0 b0
cp a1 b1
cp a2 b2
cp a3 b3
cp a4 b4
cp a5 b5

この例では規則的なファイル名であることが前提になっているため、もし作成元と作成先のファイル名に関連がない場合にはもっと工夫する必要があるかもしれません。

id:snpia

ご回答ありがとうございます!

とてもわかりやすいコードを例示していただいたおかげでRake::Task.invokeの使い方がよくわかりました。

私の探し方が悪いのかウェブ上の情報はどうも断片的で,いろいろ誤解していたようですが,理解がまとまりました。

2011/01/10 21:27:54

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません