関数コンテクスト、thisについて

Squirrelでは関数実行には関数そのものと同時にコンテクストとなる変数(environmentとも呼ばれる)を指定する必要がある。この変数は関数内ではthisとしてアクセス可能なほか、関数内で出現する変数や関数などの名前はコンテクスト内を最優先に検索される。Squirrelスクリプト上で呼びだす際にはこの変数は状況に応じて自動的に設定される。例えばSquirrelスクリプト内でTというテーブル内のF()という関数をT.F()という呼び方をすれば、このときのF()内のthisはTを指す。

sq.exeを立ち上げてプロンプトから直接foreach(k,v in this) { print(k + "=" + v + " "); }と入力すれば、root tableに登録されているグローバルな変数や関数の名前が出力される。このことからプロンプトに入力された命令がroot tableをコンテクストとして実行されたことが分かる。

Fという関数があった場合にF.call(a);とすれば明示的にコンテクストとしてaを指定して関数を実行することもできる。また関数自体にはデフォルトのコンテクストへの弱参照をしまっておけるようになっており、bindenv()を使うことでここへ値を設定できる。例えばインスタンスのメソッドをコールバックとしてどこかへ登録する際に使えるだろう。詳しくはマニュアルを参照されたい。

Squirrelスクリプトの記述上はコンテクストは暗黙で設定されており、存在していないように見えるが、実際に行われるスタック操作ではあくまで関数呼び出しの際、常に1番目に設定される引数なのである。これを認識しておかないとC++側でSquirrel関数を実装したり呼び出したりする際に面食らうことになる。