「PIONE定義書のTIPS」の版間の差分
(→記述例) |
|||
(同じ利用者による、間の2版が非表示) | |||
行59: | 行59: | ||
</pre> | </pre> | ||
orを使用して、出力ファイルを結合するとnthを使って呼び出すことができます。これにより例えばファイル名を変更した場合でもoutputの部分だけ変更すれば良いことになります。(参照:[[PIONEチュートリアル#基本13(orの使用例)]]、[[PIONEの式#シーケンス]])<br> | orを使用して、出力ファイルを結合するとnthを使って呼び出すことができます。これにより例えばファイル名を変更した場合でもoutputの部分だけ変更すれば良いことになります。(参照:[[PIONEチュートリアル#基本13(orの使用例)]]、[[PIONEの式#シーケンス]])<br> | ||
+ | <br> | ||
+ | |||
+ | === 条件文を作りたい === | ||
+ | [[PIONEチュートリアル#基本7(条件文)]]をご覧下さい。この条件文はAction文以外で使用可能です。(Action文内はシェルスクリプト)<br> | ||
+ | <br> | ||
+ | |||
+ | === ループ文を作りたい === | ||
+ | ファイル毎によるループ文の例については[[PIONEチュートリアル#実行例15(ループ文3)]]をご覧下さい。変数毎のループ文の例については[[#eachとallについて]]をご覧下さい。<br> | ||
<br> | <br> | ||
行187: | 行195: | ||
("PADMODE":$PADMODE) | ("PADMODE":$PADMODE) | ||
</pre> | </pre> | ||
+ | <br> | ||
== 記法の注意点 == | == 記法の注意点 == |
2015年3月15日 (日) 23:45時点における最新版
ここでは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チュートリアル#基本7(条件文)をご覧下さい。この条件文はAction文以外で使用可能です。(Action文内はシェルスクリプト)
ループ文を作りたい
ファイル毎によるループ文の例についてはPIONEチュートリアル#実行例15(ループ文3)をご覧下さい。変数毎のループ文の例については#eachとallについてをご覧下さい。
lengthの使用例
'*.txt'.allのようにallで宣言した入力ファイルはデータ型のシーケンスとして取り扱えるので、PIONEの式#シーケンスのlengthを使用すると、入力ファイル数を得ることができます。
例. allで読み込むファイル数が2以上のときのみ実行する場合
Rule Main input '*.txt'.all output 'data.log' constraint $I[1].length() > 1 Action touch {$O[1]} End
eachとallについて
eachとallはシーケンスのメソッドですので、入出力ファイルに限らずパラメータや演算などでも使用可能です。(参照:PIONEの式#シーケンス)
Rule Main output 'data.txt' param $i := ((-60/10).upto(60/10)*10).all() Action for i in {$i} do echo "${i}" >> {$O[1]} done End
上記の場合、パラメータをひとまとめにしたルールが1つ動作します。
==> &Anonymous:Root([],{}) --> Rule Application: &Anonymous:Root([],{}) --> Distribution: &Anonymous:Root([],{}) >>> &Anonymous:Main([],{i:(<i>-60|-50|-40|-30|-20|-10|0|10|20|30|40|50|60)}) ==> &Anonymous:Main([],{i:(<i>-60|-50|-40|-30|-20|-10|0|10|20|30|40|50|60)}) SH ------------------------------------------------------------ SH for i in -60 -50 -40 -30 -20 -10 0 10 20 30 40 50 60 SH do SH echo "${i}" >> data.txt SH done SH ------------------------------------------------------------ <== &Anonymous:Main([],{i:(<i>-60|-50|-40|-30|-20|-10|0|10|20|30|40|50|60)}) <-- Distribution: &Anonymous:Root([],{}) <-- Rule Application: &Anonymous:Root([],{}) <== &Anonymous:Root([],{})
allを除いた場合はeachとして各パラメータ毎にルールが動作します。
==> &Anonymous:Root([],{}) --> Rule Application: &Anonymous:Root([],{}) --> Distribution: &Anonymous:Root([],{}) >>> &Anonymous:Main([],{i:(<i>-60)}) >>> &Anonymous:Main([],{i:(<i>-50)}) >>> &Anonymous:Main([],{i:(<i>-40)}) >>> &Anonymous:Main([],{i:(<i>-30)}) >>> &Anonymous:Main([],{i:(<i>-20)}) >>> &Anonymous:Main([],{i:(<i>-10)}) >>> &Anonymous:Main([],{i:(<i>0)}) >>> &Anonymous:Main([],{i:(<i>10)}) >>> &Anonymous:Main([],{i:(<i>20)}) >>> &Anonymous:Main([],{i:(<i>30)}) >>> &Anonymous:Main([],{i:(<i>40)}) >>> &Anonymous:Main([],{i:(<i>50)}) >>> &Anonymous:Main([],{i:(<i>60)}) ==> &Anonymous:Main([],{i:(<i>-60)}) SH ------------------------------------------------------------ SH for i in -60 SH do SH echo "${i}" >> data.txt SH done SH ------------------------------------------------------------ <== &Anonymous:Main([],{i:(<i>-60)}) ==> &Anonymous:Main([],{i:(<i>-50)}) -中略- <== &Anonymous:Main([],{i:(<i>50)}) ==> &Anonymous:Main([],{i:(<i>60)}) SH ------------------------------------------------------------ SH for i in 60 SH do SH echo "${i}" >> data.txt SH done SH ------------------------------------------------------------ <== &Anonymous:Main([],{i:(<i>60)}) <-- Distribution: &Anonymous:Root([],{}) <-- Rule Application: &Anonymous:Root([],{}) <== &Anonymous:Root([],{})
この記法を利用することで特に複数のfor文にてeachやallの処理を切り替えることが容易にできます。
Rule Main output '*.txt'.all Flow rule Sub {i:1.upto(3).each, j:1.upto(3).all, k:1.upto(3).all} End Rule Sub output '*.txt'.all Action for i in {$i} do for j in {$j} do for k in {$k} do touch ${i}-${j}-${k}.txt done done done End
シーケンスの要素が多くなったとき
シーケンスの要素が多くなり、1行で記述すると可読性が落ちるときは下記のように改行を使用します。
$Config := ("CLUSTER":$CLUSTER) | ("PADWIDTH":$PADWIDTH) | ("PADHEIGHT":$PADHEIGHT) | ("SHRINK":$SHRINK) | ("PADMODE":$PADMODE)
記法の注意点
パラメータと変数束縛の違い
PIONE定義書において、値を取り扱うときにパラメータもしくは変数束縛を使用することもしばしばあります。この2つは取り扱いが異なりますので、混同しないように気をつけましょう。また、これらを使う主な目的はFlow内の条件文などで使用することにあります。Action内に記述するときはシェル変数などとも区別しましょう。両者の違いについてはPIONE定義書を参照して下さい。
デバッグ
構文エラーに関する注意点
下記に陥りやすい構文ミスやルールを記載します。
*rule名の先頭を数字で定義することはできない。(× 3Dto2D, ○ Ref3Dto2D)
*rule名にハイフンを含めることはできない。(× Ref3D-2D, ○ Ref3D_2D)
*ルールヘッダーは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