MetaPostの変数
MetaPost の変数についてのまとめ
参考文献
- Hobby, John D. "A user’s manual for MetaPost." Computing Science Technical Report 162 (1992).
以下マニュアルと記載する.
変数名
(詳細についてはマニュアルの 7 Variables 参照)
変数について, マニュアルの記載は以下の通り. これでわかる人にはわかるらしい.
<variable> → <tag><suffix>
<suffix> → <empty>|<suffix><subscript>|<suffix><tag>
<subscript> → <number>|[<numeric expression>]
大雑把なイメージとしては,
- 変数は予約語でない文字列(tag)に添字(suffix)がついたもの
- 添字はなくてもいいし, 数字(subscript)でも文字列(tag)でもよい
- 数値変数(numeric expression)を添字にする場合は角カッコで囲む
マニュアルに記載の例:
-
alpha
,==>
,@&#$&
,~~
-
f.top
,f.bot
-
x2r
,x3r
,x3.14r
x[i]r
結構広い範囲の文字列が変数名(tag)として有効(1.). オブジェクトのプロパティのように, ピリオドによりタグを区切ることができる(f
に添字としてtop
もしくはbot
が付いている)(2.). 添字が数字の場合はピリオドはいらない, また, 数字の中のピリオドは小数点と解釈される(3.). 数値変数を添字にする場合には角カッコで囲む(普通のプログラミング言語の配列と同じような書き方ができる)(4.).
変数宣言
変数は基本的に型を宣言してから使用する. MetaPost で使用できる型は, numeric
, pair
, path
, transform
, (rgb)color
, cmykcolor
, string
, boolean
, picture
, pen
の10種類.
宣言で注意する点は以下のとおり.
- 宣言なしで変数を使用すると, 型は
numeric
になる - 宣言の直後では値は未定義になる
-
beginfig(); ... endfig;
の間では,x
,y
,z
(およびその添字付きの変数)は宣言なしでローカル変数(beginfig
,endfig
のブロックの外側の影響を受けない)となり,z<suffix>=(x<suffix>,y<suffix>)
である - 数字の添字(配列)を持つ変数は個別に宣言できず, 配列として宣言する
例えば, 次のような宣言はできない.
numeric q1,q2,q3;
代わりに以下のように宣言する.
numeric q[];
(角カッコを付けないと添字なしのq
という変数だけが未定義になる.)
代入と方程式
(詳細についてはマニュアルの 5 Linear Equation 参照)
通常のプログラミング言語と異なり, =
は代入を意味せず, 等しいこと, つまり方程式を表す. 驚くべきことに, MetaPostは線形(1次)方程式を自動的に解いてくれる. 例えば, 以下の連立方程式は,
a+b=3;2a=b+3;
以下と同じである.
a=2;b=1;
一方代入には :=
を使う. 例えば, インクリメントは以下のように書く.
a:=a+1;
ここで等号を使って a=a+1;
としてしまうと, ! Inconsistent equation
と言われエラーになる.
このように, 値を設定する, という意味では似ているが, 方程式と代入は意識して使い分ける必要がある.
a=2;b=a;a:=3;c=a; %%% 3つ目の式だけ代入
この例では前から順番に解釈することにより, 正しく値を設定できる. 仮に3つ目を a=3;
としてしまうと, 1つ目の a=2;
と矛盾するのでエラーになる.
スコープ
(詳細についてはマニュアルの 10 Macros 参照)
MetaPostでは begingroup; ... endgroup;
で囲むことにより文をグルーピングすることができる. しかし, グルーピングするだけでは中の変数はローカルにならない.
x23=3.1;
begingroup;
y3a=1;x23:=2;
endgroup;
show x23,y3a;
これを実行すると, グルーピング内の式が反映され, 2と1という結果が表示される. グルーピング内の変数をローカルにするためには save
を使用する.
x23=3.1;
begingroup;
save x,y; %%% 追加
y3a=1;x23:=2;
endgroup;
show x23,y3a;
こうすると, 3.1 と y3a
(未定義) が表示され, グルーピング内で変数 x
, y
がローカルになっていることがわかる. 変数宣言の場合と異なり, save x,y;
だけで(つまり, 角カッコなしで) x
, y
に添字がついた変数もすべてローカルになる.
ちなみに, 変数宣言の項で述べた, beginfig(); ... endfig;
の間で, x
, y
, z
がローカル変数になる, のは, beginfig;
が begingroup;save x,y;
のように展開されるためである.
逆に他の変数はローカルではないので、例えば beginfig(1)
と beginfig(2)
で同じ変数を使用する場合には各 beginfig
で使用前に宣言を行う(宣言により未定義に戻る), もしくは, 明示的に save
を使ってローカル変数にする, 等の対策をしたほうがよいと思われる.
Discussion