Specript Language Reference rev.0.7.0 | www.specript.org |
namespaceは、JavaのpackageやC++/C#のnamespace同様、定義されるproperty、function、 specの所属する名前空間を規定するものです。
namespace宣言は、ソースコードファイルの先頭に記述し、そのソースコードファイル内で 定義されるproperty、function、specの所属するnamespaceを定めます。
namespace
"
<namespace名> ( "::
" <namespace名> )*
";
"
namespace 商品;
namespace 商品::在庫;
namespace宣言はソースコードファイルの先頭に他の宣言や定義に先立って記述します。 namespace宣言より前に他の宣言や定義があってはいけません。namespace宣言を省略する ことはできません。
namespace宣言の記述されたソースコードファイルにて定義されたproperty、function、 specは、そのnamespaceに所属することとなります。
namespace
ですが、記法はJavaのpackage風と
なっています。C++/C#のようにnamespace適用範囲を"{
"〜"}
"で
括ってブロックとするような記述方法ではありません。1つのソースコードファイル内に
定義されるproperty、function、specは、常に同一のnamespaceに属することとなります。
namespaceは階層を持つことができます。namespaceの階層の区切りはC++風の"::
"です。
例えば、namespace "A::B::C
"に属するproperty "p
"を、
他のnamespace内のプログラムコードから参照するとき、"A::B::C::p
"と記述します。
namespaceの階層はプログラムコードの管理上の便宜を図るものですが、本節第3項に
示すような可視範囲決定の根拠にもなります。
あるnamespaceにて定義されるproperty、function、specの名称たる識別子は、そのnamespace内に
おいてproperty、function、spec全体の中でユニークでなければなりません。例えば、
"X
"という名称をもつpropertyを定義した場合、同一namespace内で
他に"X
"という名称を持つpropertyは定義できません。さらに、同一namespace内で
"X
"という名称を持つfunctionやspecも定義できません。
複数のソースコードファイルに同一のnamespace宣言を記述しても構いません。この場合、 前段における識別子のユニーク性については、同一namespaceが宣言される全ての プログラムコード(リンクする全てのソースコードおよび実行可能コード)内にてユニークで なければならないこととなります。
ただし、後述するprivate修飾子が付与された場合は、定義する識別子は、その識別子が 定義されるソースコードファイル内で定義される全ての識別子、および同一namespaceが 宣言される他のプログラムコードファイル内にて定義されるprivateでない識別子、これらと 重複しなければよいこととなります。言い換えると、他のプログラムコードファイル内で 定義されるprivateな識別子とは重複してよいこととなります。
namespaceの名称とソースコードファイルのファイル名、namespace階層とソースコードファイルの 格納ディレクトリ階層との間に特に制約や規約はありません。namespace名と ソースコードファイル名は異なっていて構わないし、namespace階層とファイルの 格納ディレクトリ階層が一致していなくても構いません。
1つのソースコードファイルに複数のnamespace宣言を記述することができます。この場合、 そのソースコードファイル内に定義されるproperty、function、specは、いずれのnamespaceにも 所属する、ということとなります。
[代理店.spec]namespace マスター管理::代理店; namespace 商品::会計::売掛; namespace 商品::在庫::販売管理; spec 代理店仕様 : { ... }[納品処理.spec]namespace 商品::在庫::販売管理::納品; property とある代理店 : 商品::在庫::販売管理::代理店仕様 = ... ;[請求処理.spec]namespace 商品::会計::売掛::請求; property とある代理店 : 商品::会計::売掛::代理店仕様 = ... ;
上記例では、ファイル[代理店.spec]には3つのnamespaceが宣言されています。
[代理店.spec]内で定義されるspec "代理店仕様
"は、3つのnamespace、
マスター管理::代理店
"商品::会計::売掛
"商品::在庫::販売管理
"のいずれにも属することとなります。
そして、ファイル[納品処理.spec]においては、"代理店仕様
"を
商品::在庫::販売管理::代理店仕様
"商品::会計::売掛::代理店仕様
"として使用しています。
このように、同一のproperty、function、specの定義を、業務の文脈に応じて異なるnamespaceに 所属するものとして、使い分けることができます。
namespaceが異なるproperty、function、specは、デフォルトで可視範囲に制限がかかります。
property、function、specの各定義にpublic
、private
といった
修飾子を付与することで可視範囲が変わります。
namespaceに所属するproperty、function、specは、デフォルトでは自namespace内、 および系列下位のnamespaceから可視となります。
[X.spec]namespace A; property pa = ...; // 自namespace内で定義されるpropertyを参照可能です。 property q = pa; // namespace系列下位で定義されるpropertyは参照不可です。 property r = A::B::pb; // コンパイル時エラー property s = A::B::C::pc; // コンパイル時エラー property t = A::B2::pb2; // コンパイル時エラー[Y.spec]namespace A::B; property pb = ...; // namespace系列上位で定義されるpropertyが参照可能です。 property q = A::pa; // namespace系列下位で定義されるpropertyは参照不可です。 property r = A::B::C::pc; // コンパイル時エラー[Z.spec]namespace A::B::C; property pc = ...; // namespace系列上位で定義されるpropertyが参照可能です。 property q = A::pa; property r = A::B::pb;[W.spec]namespace A::B2; property pb2 = ...; // namespace系列上位で定義されるpropertyが参照可能です。 property q = A::pa; // 他系列で定義されるpropertyは参照できません。 property r = A::B1::pb1; // コンパイル時エラー
property、function、specの各定義にprivate
修飾子を付与すると、
自ソースコードファイル内でのみ可視となり、系列下位のnamespaceや、同一namespaceでも
他のファイルからは不可視となります。
[X.spec]namespace A; // private修飾子が付いています。 private property pa = ...; // privateでも自ファイル内では参照可能です。 property q = pa;[Y.spec]namespace A::B; // privateなのでnamespace系列上位で定義されるpropertyでも参照不可です。 property r = A::pa; // コンパイル時エラー[Z.spec]namespace A; // "pa"は同一namespaceですが、privateなので、ファイルが異なる場合は参照不可です。 property s = pa; // コンパイル時エラー
property、function、specの各定義にpublic
修飾子を付与すると、他系列の
namespaceを含む全てのnamespace、全てのファイルから可視となります。
[X.spec]namespace A; // namespace系列下位で定義されるpropertyもpublicなので参照可です。 property q = A::B1::pb1; property r = A::B2::pb2;[Y.spec]namespace A::B1; // publicです。 public property pb1 = ...;[Z.spec]namespace A::B2; // publicです。 public property pb2 = ...; // "A::B1::pb1"はpublicなので他系列からも参照可です。 property q = A::B1::pb1;
他namespaceに属するproperty、function、specを参照、呼び出し、使用するとき、 namespace付きの ‘フルネーム’で記述しなければなりませんが、alias定義を行うと、 定義されたnamespaceの(より短い)別名を用いてproperty、function、specの参照、 呼び出し、使用ができます。
alias
"
<alias名>
":
" <namespace名> ( "::
" <namespace名> )*
";
"
alias 在庫 : 商品::在庫;
alias定義は、各ソースコードファイルの先頭、namespace宣言の後に複数個記述できます。
[X.spec]namespace A::B::C; public property p = 3;[Y.spec]namespace D::E::F; // namespace "A::B::C"の別名"C"を定義します。 alias C : A::B::C; // "p"参照時、"A::B::C::p"ではなくalias定義された別名を用いて"C::p"と記述しています。 property q = C::p; // q == 3となります。
aliasによるnamespaceの別名定義は、それが記述されたソースコードファイル内でのみ有効です。
複数個のaliasを定義するとき、同じ別名を定義しようとするとコンパイル時エラーとなります。
[X.spec]namespace X; // 同一の別名を定義しようとするとコンパイル時エラーとなります。 alias A : A::B::C; alias A : A::B; // コンパイル時エラー
alias定義された別名が本来のnamespace名と衝突しているとき、常に別名が優先されます。
[X.spec]namespace A::B::C; public property p = 3;[Y.spec]namespace C; public property p = 4;[Z.spec]namespace D; alias C : A::B::C; // "C::p"は、alias定義が優先されnamesapce "A::B::C"の方の"p"が参照されます。 property q = C::p; // q == 3となります。
別名に階層を持たせることはできません。
// 定義する別名に階層は持たせられません。 alias X::Y : A::B::C::D; // コンパイル時エラー
(c)2007-2008, Specript Development Team | Last Updated: 2008-03-06 |