変数のスコープとは何ですか。

MAXScript に関する質問と回答 > 変数のスコープとは何ですか。

この章では、変数のスコープについて詳しく説明します。

変数 - 代入およびスコープ

変数のスコープ

外部コードからロールアウトのローカルおよび他の項目へのアクセス

未定義の暗黙的グローバル変数の変更

定義構造に含まれるトップ レベルのグローバル変数宣言

永続グローバル変数

「::」を使用してグローバルとしてグローバル変数を指定

スコープ外にある変数にスコープ内でアクセスできるように定義する理由

スコープは、ネストされた「レイヤ」による玉ねぎのようなものとして考えることができます。ローカル変数が特定のレベルで作成された場合、その変数はこのレベルでのみ表示され、スコープはすべてその内側にネストされています。

MacroScripts、ロールアウトおよびユーティリティといった特別な事例では、一番外側のスコープで定義されたローカル変数は、macroScript、ロールアウト、またはユーティリティ内部のコードでは見ることができますが、その他の macroScript、ロールアウト、またはユーティリティでは見ることができません。これは、「プライベート グローバル」変数と見なすことができます。この名前は動作方法を示すだけのもので、新しい種類のスコープを示す技術的な名称ではありません。詳細は、「プライベート グローバル変数としてのローカル変数」を参照してください。

また、変数は定義済みである場合のみアクセスできます。つまり、ソース コードの後方で定義されている関数やロールアウトにアクセスできないのは、関数とロールアウト定義の順序が原因なのです。こうした問題は、関数やロールアウトを保存するために使用する変数を、実際の関数またはロールアウト定義の前に、同じスコープかそれよりも上位のスコープであらかじめ定義しておくことで解決できます。

たとえば、ユーティリティ内に複数のロールアウト定義があり、最初のロールアウトの内部から 2 番目のロールアウトのユーザ インタフェース要素にアクセスする場合、最初のロールアウトよりも前に 2 番目のロールアウトを保存する変数をあらかじめ定義しておく必要があります。

変数を事前定義しないで 2 番目のロールアウトから UI コントロールにアクセスしようとすると、最初のロールアウトの評価時に 2 番目のロールアウトに関する情報がないために、MAXScript からエラーが表示されます。

2 番目のロールアウトはまだ評価されていないからです。2 番目のロールアウトの変数名がユーティリティの最初でローカルとして宣言されている場合は、最初は値「undefined」が設定されますが、これは参照コードによってあとで定義されるものと見なされます。つまり、MAXScript は変数の名前を見つけたときに、その内部にはロールアウト値がまだ存在していないことを無視して評価を続けます。2 番目のロールアウトの定義を見つけた時点でそのロールアウト情報を「入力」するので、実際に最初のロールアウトを使用して 2 番目のロールアウトを参照するときには何の問題も起こらないわけです。

ローカル変数とグローバル変数を宣言する理由

ローカル変数によって、スクリプトの他の部分、さらには他のスクリプトすらも干渉することなく「ローカル使用」する値がカプセル化されます。その外側にある単一のスクリプトがすべてグローバル変数のみを使用している場合を想定してみましょう。あるユーザがループ内で「i」を使用したスクリプトを記述し、別のユーザがどこかの頂点のインデックスに「i」を使用した別のスクリプトを記述した場合、これら 2 つのスクリプトが同じシーン内で実行されると、特に注意して変数を使用前に明示的に宣言して初期化しない限り、問題が発生します。すべてを一緒にしてしまうと、本当に厄介です。

幸運にも、MAXScript では変数がそれぞれのスコープ内で保持され、明示的なグローバル定義を行わない限り、他のスクリプトの変数にアクセスすることは絶対にできません。

既定値では、スコープ内で定義されずに使用されている変数はすべてそのスコープ用のローカル変数となり、通常、各変数の冒頭に「local」と明示的に記述する必要はありません。変数を明示的に宣言するのはプログラミングの練習をする上では好ましいことですが、ほとんどの場合 MAXScript ではこの宣言は強制されません。詳細は、「暗黙的な変数宣言」を参照してください。

複数のスクリプトが同じ値にアクセスしたり、1 つの値を共有する場合は常に、グローバル変数を定義します。どの MAXScript コードでもこの値を読み込むことができます。したがって、変数内にいくつかの基本設定を保存する macroScript と、これらの基本設定を使用するユーティリティがある場合、これら 2 つが認知しておかねばならないのは共通グローバル変数の名前だけで、相互を認知する必要はありません。

上位スコープですでに同じ名前の変数が存在しているが、ネストしたスコープ内でどうしてもその名前を使用したい場合などは、ローカル変数を明示的に宣言することになります。明示的にローカルな変数であることを宣言していないと、外側の変数にある値にアクセスしてしまって論理的な問題が発生することになります。

関連事項