デバッグのための条件文

提供: Eospedia
2016年4月20日 (水) 03:23時点におけるTakahiro (トーク | 投稿記録)による版

(差分) ←前の版 | 最新版 (差分) | 次の版→ (差分)
移動: 案内検索

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はファイル無しを意味します。