プログラミングでのスコープ(scope, 可視範囲)とは、ある変数名や関数名といった名前を参照できる範囲のこと。ある範囲の外に置いた変数等は、通常、その名前だけでは参照できない。このときこれらの変数はスコープ外である、「見えない」といわれる。

プログラミングでは、予期しない誤作動を避けるためにも、それぞれの作業段階で必要のない名前はできるだけ参照されないようにすることが望ましい(特に、大域変数は便利な場合もあるが、危険でもある)。たとえば、CERT C コーディングスタンダードには、「変数と関数の有効範囲を最小限にする」(DCL19-C.)[1]というレコメンデーションがある。

目次

スコープとエクステント編集

非常に多くのプログラマがスコープと混同しているものに、エクステント(extent。「スコープ」の「可視範囲」に対して、「生存期間」(lifetime)とも)がある。スコープは変数などの名前について議論されるものであり、エクステントはその内容について議論されるものである。例えばC言語において、ローカル(関数内)スコープの変数にstaticという修飾を付けると、その名前のスコープは変わらないが、その内容のエクステントは変化する。

後述する「動的スコープ」などにも、厳密にはスコープとエクステントの混同がある( https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node43.html などを参照)。

スコープの種類編集

構文範囲からの分類編集

大域スコープ (global scope)
プログラムの「全体」から見えるスコープのこと。このスコープに属する変数は大域変数といわれる。BASICのような単純な言語では大域スコープしか存在しない場合がある。Pythonのような大域変数の書き換えが簡単には行えない言語も存在する。
ファイルスコープ (file scope)
大域スコープと似ているが、プログラムを記述したファイルの内側でのみ参照できるスコープ。プログラムが複数のファイルから構成される場合は他のファイルから参照することはできない。
局所スコープ (local scope)
ある関数やブロックの範囲内に限定されたスコープのこと。何を持って範囲を与えるかは言語により様々だが、一般に入れ子のローカルスコープは外側を参照できるのが普通である。このとき兄弟関係にあるスコープは見えない。変数宣言が必要な言語の場合は宣言文以降にスコープが制限される場合が多い。
インスタンススコープ (instance scope)
クラスベースのオブジェクト指向言語で、各インスタンス毎に割り当てられた変数が所属メソッド(メンバ関数)からのみ参照されるスコープのこと。いわゆるカプセル化はこれを指す。保護されない変数の場合は、クラス定義が見えていてオブジェクトにアクセスできる場合は直接参照できる。C言語構造体参照なども一種のインスタンススコープである。
クラススコープ (class scope)
クラスベースのオブジェクト指向言語で、あるクラスの定義全体から参照できるスコープ。インスタンススコープと異なり変数が共有されるので、ある種の制限された大域スコープと考えることができる。クラススコープをもたない言語の場合でも、ファイルスコープを用いることで同様の機構を実現できる場合がある。ある特定のクラスだけなのか、派生クラスまでも含むのかによってそれぞれクラスインスタンススコープ/クラススコープとさらに細分化する。

スコープ導入からの分類編集

静的スコープ (static scope) 
構文スコープ (lexical scope)。構文上で決定されるスコープ。
動的スコープ (dynamic scope) 
実行時の関数の親子関係で名前を導入が導入されるスコープ。関数が呼び出し元で展開されたかのようなスコープが構成される。実行時に名前による解決が必要なため、普通にコンパイルしてこれを実現するのは面倒である。
名前空間 (namespace) 
厳密にいえば名前空間自体はスコープそのものではなく、スコープを導入する機構である。おおまかに2通りのものを名前空間と呼んでいる。(1)名前の集合を定義するもので、任意のタイミングで名前空間を導入し、定義された名前を参照可能にすることができる。名前空間では持続範囲を指定できるため、外部で必要のない名前の拡散を避けることもできる。名前空間自体も一種のスコープを持ち、名前空間の名前によって参照される。この視点では、上記のファイルスコープやローカルスコープも暗黙の名前空間でスコープを構成していると考えられる。ただし無名であり、外部に導入できない名前空間である。
(2)ごく単純なプログラミング言語を除いて、たとえば構造体のメンバ名などは、他の名前と干渉せず、その構造体の中でユニーク(唯一)であれば任意の名前が使える(予約語と同一の場合は制限されることもある。字句や構文の都合にもよる)。そのような「名前が干渉せず、区切られている」それぞれの空間を名前空間という。Lispにおける「Lisp-1とLisp-2の議論」などがある。

編集

関連項目編集