パラメータをファイルに書きだしたい
数値シュミレーションを異なるパラメータで回したときに、そのパラメータをファイルに書きだしておきたいことは日常的にある。そんなときには次のようなコードを書くだろう。
a=1
open("data.dat","w") do ofile
println(ofile,"a=",a)
end
しかしこの方法ではパラメータが多くなれば、書くのも面倒だしコードも長くなる。
それとは別に、シミュレーションの都合上、一時的にパラメータが定義されていないときには、エラーが出てしまう。それをいちいちコメントアウトするのも面倒だ。なので次のようなmacroを書いた。
macro output_parameter(file,param)
esc(:(
if(@isdefined $param)
println($file,$(string(param)),"=",$param)
else
println($file,$(string(param)),"=nil")
end
))
end
# Usage
a=1
b=2
open("data.dat","w") do ofile
@output_parameter(ofile,a)
@output_parameter(ofile,b)
end
# data.dat
# a=1
# b=2
このmacroはファイルとパラメータ名だけ渡せばファイルに、いい感じに出力される。しかもパラメータが未定義の場合はエラーをはかずに=nilを出力する。
更に多くのパラメータがあっても、コードを増やさないために、上のmacroの上に次のmacroを書いた。
macro output_parameters(file,params)
str="begin\n"
for i in eval(params)
str*="@output_parameter($file,$i)\n"
end
str*="end"
esc(Meta.parse(str))
end
#Usage
a=[1,2]
b="str"
open("data.dat","w") do ofile
@output_parameters(ofile,[:a,:b])
end
# data.dat
# a=[1,2]
# b="str"
これでパラメータが増えても、[:a,:b,...]と増やしていくだけで、いい感じにファイルにアウトプットされる。
juliaのmacro初心者なので、何度がつまづいた。
今回つまづいたのは、begin ... end というので書こまないとエラーが出るところ、そしてesc(...)を忘れると、macroが展開されたときに外側の環境が引きつげなくて、"a" is not defined 的なエラーが出るところである。