PIONE定義書のTIPS
ここではPIONE定義書に関するTIPSを示します。実装例はPIONEチュートリアル、PIONEチュートリアル-PNML、実行例はPIONE Webclientチュートリアルをご覧下さい。
目次
記述例
入出力ファイルの宣言
inputやoutputで宣言する入出力ファイル名は通常' '(シングルクォート)で囲みます。これは入出力ファイルをPIONEにおけるデータ表現型として宣言しなければならないためです。' '(シングルクォート)で囲まれた部分がデータ表現型になります。(参照:PIONEの式#データ表現型)
Rule Main
input '1.txt'
output '2.txt'
Action
cp {$I[1]} {$O[1]}
End
inputやoutput以降は最終的にデータ表現型であればよいので、' '(シングルクォート)で囲まなくても文字列型を経由してメソッドd()を使用すれば同様に入出力ファイルとして使用できます。(参照:PIONEの式#文字列型(string))
Rule Main
input "1.txt".d()
output (2.str()+".txt").d()
Action
cp {$I[1]} {$O[1]}
End
出力ファイルのパターンが異なる場合
条件によって(入力ファイル名).outか(入力ファイル名)-Info.outのどちらかを出力するルールについて考えます。
param $Mode := 0
Rule Main
input '*.txt'
output '*.out'.all
Action
if [ {$Mode} -eq 0 ] ; then
cp {$I[1]} {$I[1][1]}.out
else
wc {$I[1]} > {$I[1][1]}-Info.out
fi;
End
outputでの宣言を'*.out'.allで全ての.outファイルを対象としてAction内で実際に出力ファイル名を個別に指定しています。{$I[1][1]}.outや{$I[1][1]}-Info.outの処理が多い場合には可読性が落ちます。ファイル名を変更したい場合にも対応しきれない可能性があります。
param $Mode := 0
Rule Main
input '*.txt'
output '{$I[1][1]}.out' or '{$I[1][1]}-Info.out'
Action
if [ {$Mode} -eq 0 ] ; then
cp {$I[1]} {$O[1].nth(1)}
else
wc {$I[1]} > {$O[1].nth(2)}
fi;
End
orを使用して、出力ファイルを結合するとnthを使って呼び出すことができます。これにより例えばファイル名を変更した場合でもoutputの部分だけ変更すれば良いことになります。(参照:PIONEチュートリアル#基本13(orの使用例)、PIONEの式#シーケンス)
記法の注意点
パラメータと変数束縛の違い
PIONE定義書において、値を取り扱うときにパラメータもしくは変数束縛を使用することもしばしばあります。この2つは取り扱いが異なりますので、混同しないように気をつけましょう。また、これらを使う主な目的はFlow内の条件文などで使用することにあります。Action内に記述するときはシェル変数などとも区別しましょう。両者の違いについてはPIONE定義書を参照して下さい。
デバッグ
構文エラーに関する注意点
下記に陥りやすい構文ミスやルールを記載します。
*rule名の先頭を数字で定義することはできない。(× 3Dto2D, ○ Ref3Dto2D)
*ルールヘッダーはRule、フロー定義ではruleを書く。
*Mainルールのinputファイルはpione-clientの-iで指定しているディレクトリ内に全てあるか。
*Mainルールのoutputファイルは必ずいずれかのルールで全て作成されているか。
*パラメータのブロック定義はルール内では使用できない。
*input, outputで宣言するファイル名は基本的に' '(シングルクォート)で囲む。(参照:#入出力ファイルの宣言)
pione action execをPIONE定義書で使用したいとき
pione action execはアクション文書(.mdファイル)のマークダウンで記述されたルールを単独で実行することができますので、デバッグの際に非常に有効なコマンドであるといえます。しかし、このpione action execは通常のPIONE定義書に対応していません。元のアクション文書が無い場合(コンパイルでなく直接の記述でPIONE定義書を作成した場合)、そのままのフォーマットではpione action execが使用できません。
例えば、PIONE定義書を下記のように記述すれば、pione action execに対応でき、かつpione-clientも実行できます。
Rule Main
output 'out.txt'
Action
# この中はpione-clientのみの動作を記述可能
Out={$O[1]}
:<<:
※ ↓## (ルール名)の上は必ず1行空ける
## Main
```
# この中はpione action execのみの動作を記述可能(#:: 〜 :<<:までがどちらも実行される処理)
Out='out.txt'
#::
# この中はどちらも実行される
echo "Message for Shell"
echo "Message for File" > $Out
:<<:
```
::
# この中はpione-clientのみの動作を記述可能
End
このように記述すれば、PIONE定義書でもpione action execに対応できるようになります。
pione-clientで実行した場合
$ pione-client test.pione
==> &Anonymous:Root([],{})
--> Rule Application: &Anonymous:Root([],{})
--> Distribution: &Anonymous:Root([],{})
>>> &Anonymous:Main([],{})
==> &Anonymous:Main([],{})
-中略-
<== &Anonymous:Main([],{})
<-- Distribution: &Anonymous:Root([],{})
<-- Rule Application: &Anonymous:Root([],{})
<== &Anonymous:Root([],{})
$ cat process/output/out.txt
Message for File
pione action execで実行した場合
$ pione action exec test.pione Main Message for Shell $ cat out.txt Message for File