デバッグのための条件文
Flowを使用したルールが何重にもなっているPIONE定義書にて末端のルールについてデバッグしようとすると、出力ファイルをMainまで引き継ぐためには呼び出し元からMainのルールまでに全て宣言しなければなりません。さらに、デバッグ対象のルールを変えるたびにそれぞれを変更する必要があります。デバッグの切り替えの手間が少なくなる方法を考えてみましょう。
例えば、下記のPIONE定義書があったとします。末端のSub3にログファイル{$I[1][1]}.logを出力したいときには、下記コメントアウトの部分のようにSub2, Sub1, Mainにも{$I[1][1]}.logを出力ファイルとして宣言しなければなりません。この場合、ログを出力するかしないかで各行のコメントアウトを操作する必要があります。さらに、この構文ではSub3に1つ問題がありActionを実行する前に{$O[2]}を変換しようとするので、{$O[2]}が設定されていない場合はエラーとなってしまいます。
Rule Main input '*.txt' output '{$I[1][1]}.out' # output '{$I[1][1]}.log' Flow rule Sub1 End Rule Sub1 input '*.txt' output '{$I[1][1]}.out' # output '{$I[1][1]}.log' Flow rule Sub2 End Rule Sub2 input '*.txt' output '{$I[1][1]}.out' # output '{$I[1][1]}.log' Flow rule Sub3 End Rule Sub3 input '*.txt' output '{$I[1][1]}.out' # output '{$I[1][1]}.log' Action touch {$O[1]} # wc {$I[1]} > {$O[2]} End
そこでデバッグフラグとして変数束縛を用いて、trueのときだけログを実行できるようにします。さらにログファイル名の変更が一箇所で済むようにファイル名でも変数束縛を用いています。
$LogFlag := false $LogFile := '{$I[1][1]}.log' Rule Main input '*.txt' output '{$I[1][1]}.out' if $LogFlag output $LogFile end Flow rule Sub1 End Rule Sub1 input '*.txt' output '{$I[1][1]}.out' if $LogFlag output $LogFile end Flow rule Sub2 End Rule Sub2 input '*.txt' output '{$I[1][1]}.out' if $LogFlag output $LogFile end Flow rule Sub3 End Rule Sub3 input '*.txt' output '{$I[1][1]}.out' output $LogFile Action touch {$O[1]} if {$LogFlag} ; then wc {$I[1]} > {$LogFile} fi End
outputの宣言を囲んでいるif文について注意が必要です。Flowを持つルールではデバッグ時のみログファイルができることを期待しているので、outputの宣言をif文で制御します。Sub3のActionにて実際にログを書き込んでいる箇所で{$O[2]}を使わず、outputで登録したファイル名と同じファイル名をそのまま使用します。このときAction内のif文はシェルスクリプトで記述することに注意して下さい。
デバッグ実行時に出力したいファイルが複数ある場合は、リスト(シーケンス)にて定義し、各ルールで出力する記述方法もあります。
$Debug := false if $Debug $LogFile := ('*.info' | '*.pwd' | '*.ls' | '*.log').all else $LogFile := null end Rule Main input '*.txt' output '{$I[1][1]}.out' if $LogFile.empty?.not output $LogFile end Flow rule Sub1 End Rule Sub1 input '*.txt' output '{$I[1][1]}.out' if $LogFile.empty?.not output $LogFile end Flow rule Sub2 End Rule Sub2 input '*.txt' output '{$I[1][1]}.out' if $LogFile.empty?.not output $LogFile end Flow rule Sub3 End Rule Sub3 input '*.txt' output '{$I[1][1]}.out' if $LogFile.empty?.not output $LogFile end Action touch {$O[1]} wc {$I[1]} > {$I[1][1]}.info pwd > {$I[1][1]}.pwd ls > {$I[1][1]}.ls date > {$I[1][1]}.log End
デバッグ実行時に出力したいファイルは元々Action内で作成されているファイルをMainまであげて確認する場合も多いと思います。上記のように記述すると、末端のルールからMainまで$LodFile内のファイルを渡すことができます。なお、ここでnullはファイル無しを意味します。