デバッグのための条件文
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はファイル無しを意味します。