SSブログ

厳密な光線追跡 - その18 [光線追跡エンジンを作る]

なかなか進まないMathematicaによる光線追跡エンジンの実装。前回、使い回しするつもりのMathematicaコードはパッケージとしてまとめておいたほうがいい、ということになった。Mathematicaのパッケージの作り方をまとめる前に、Mathematicaのコンテクストについて整理しないといけない。

5.1.1  コンテクスト

Mathematicaにはいわゆる名前空間のメカニズムがそなわっている。これをコンテクスト(Context)と呼ぶ。Javaではドットで繋いだ逆順のドメインネームを使っているが、Mathematicaではコンテクストマークと呼ぶバックアクセント「`」で名前を繋ぐ。

Mathematicaを立ち上げてシンボルをひとつ定義すると、それはGlobalというコンテクストに結びつけられる。下の図-6では「x」というシンボルを作ってから「?」を使って定義を問い合わせている。
1219globalcontext.png
図-6: デフォルトのコンテクスト
あらゆるシンボルはコンテクスト(context)と簡略名(short name)からなっている。今の場合「Global`」がコンテクストで「x」が簡略名である。コンテクストと簡略名を合わせたものを完全名(full name)と呼んで、それを本来のシンボルであるとみなす。

簡略名で区別できる場合は、簡略名だけでシンボルを指定できる。つまり「太郎」くんは一人しかいないときは「太郎」呼べばその人が答えるけど、「山田太郎」と「田中太郎」がいる場合はフルネームで呼ばないとどちらかわからない。コンテクストはその役目を果たす。

ふだんMathematicaを電卓がわりに使っている程度であれば、コンテクストを意識することはなく、簡略名をシンボルそのものだと思っているというのが普通だし、それで十分で、なにもわざわざめんどくさいことをする必要はない。しかし、シンボルを読みやすくわかりやすくしようとすれば、名前の衝突の確率は増える。とくに他人に使ってもらうためのパッケージでは注意する必要が出てくる。

コンテクストにはバックアクセントがいくつあってもいい。例えば
Optics`RefractiveIndexTable`Schott`Bk7
Optics`RefractiveIndexTable`Hikari`Bk7
は別のシンボルとして扱われる。ただし、Javaと同じで階層関係を表すような機能、例えば上位のシンボルのほうが優先されるとかいうような制御はない。これはあとで説明するファイルアクセスに便利なようになっているだけである。

あるシンボルがどのコンテクストに属しているかは
In[1]:= Context[x]
Out[1]= Global`
In[2]:= Context[PrimeQ]
Out[2]= System`
なとどして調べることができる。Mathematicaの組み込みシンボルはほとんどがSystemコンテクストである。

また、現行コンテクスト(Current Context)というのがあって、シンボルが入力されると、陽に指定しないかぎりそれがデフォルトになる。現行コンテクストは
In[3]:= $Context
Out[3]= Global`
あるいは
In[4]:= Context[]
Out[4]= Global`
で調べることができる。

また、コンテクストは現行コンテクストからの相対指定ができる。コンテクストをバックアクセントで始めると、それは現行コンテクストのあとに続くとみなされる。例えば
In[5]:= `Private`asdf
Out[5]= Global`Private`asdf
というような感じである。

ちなみに、フルネーム(完全名)はひとかたまりのシンボルとして普通に使う簡略名と同じに扱われるが、コンテクストだけを取り出したときは文字列として扱われる。このへんなんとなくコンテクストの実装の仕方が伺われる。

5.1.2  コンテクストの検索

あるシンボルが入力されたとき、現行コンテクストにあればそれが評価されるが、ない場合はややこしい。現行コンテクストにそのシンボルがない場合、$ContextPathが調べられる。

$ContextPathはコンテクストの検索場所を指定している。
In[1]:= $ContextPath
Out[1]= {PacletManager`,WebServices`,System`,Global`}
現行コンテクストにシンボルがない場合、Mathematicaはこのリストの先頭から順にシンボルが定義されていないか探す。リストの最後のコンテクストにもないときには、新しいシンボルとして現行コンテクスト上に作られる、ということになる。もし、複数のコンテクストに同じシンボルがあるときは$ContextPathの前のほうにあるコンテクストのシンボルが評価される。

ややこしいけど、まとめると
  1. あるシンボルが入力される
  2. 現行コンテクスト($Context)にあるか?
  3. ある場合、それが評価される
  4. ない場合、$ContextPathの先頭にあるコンテクストを調べる
  5. あればそれが評価される
  6. ない場合、$ContextPathの次のコンテクストを同様に調べる
  7. $ContextPathの最後のコンテクストにもない場合、新しいシンボルとして現行コンテクスト上に作られる
ということになる。
nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

献立12/19献立12/20 ブログトップ

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。