名前空間とは、一意の名前およびそれに対応する値の集まりです。名前空間への参照をJSL変数に格納できます。JMPには名前空間マップが1つしかないので、名前空間の名前はグローバルです。名前空間参照は、オブジェクトを参照する他の変数と同様の変数です。それぞれの適用範囲または名前空間の中で一意でなければなりません。名前空間のメンバーは、:スコープ演算子を使って参照されます。たとえばmy_namespace:xは、my_namespaceという名前空間の中のxという名前のオブジェクトを参照します。独自の名前空間の作成方法および管理方法については、ユーザ定義による名前空間の関数を参照してください。名前空間は、異なるスクリプト間での名前の競合を回避するのに特に便利です。
独自の名前空間を作成し、関連する変数および関数の定義セットを入れることができます。名前空間の管理に使用できる関数には、次のものがあります。
nsref = New Namespace( <"nsname">, <{ name = expr, ... }> );
これは、nsnameという新しい名前空間を作成し、その名前空間への参照を戻します。引数はすべてオプションです。
nsnameは、名前空間名の内部グローバルリストに格納される名前空間の名前です。nsnameは、スコープ変数の接頭辞としても使用できます。この関数は名前空間への参照を戻します。また、スコープ変数参照の接頭辞としても使用できます。nsnameを指定しなかった場合、名前空間が匿名となり、JMPによって作成された一意の名前が付けられます。Show Namespace()は、すべての名前空間とそれらの名前(指定名/匿名に関わらず)を表示します。
重要: nsnameで指定した名前の名前空間がすでに存在する場合は、それが上書きされます。つまり、スクリプトの開発時に、名前空間をクリアまたは削除しなくても、スクリプトを変更して再実行できます。間違って上書きしてしまうのを避けるには、匿名の名前空間を使用するか、または、次のようにして、特定の名前空間がすでに存在しているかどうかを確認します。 If( !Namespace Exists( "nsname" ), New Namespace( "nsname" ) ); |
名前空間を作成する際の、名前付き式のリストはオプションです。nameは、名前空間内でのみ存在するJMP変数です。
メモ: 名前付き式は、カンマで区切ったリストで指定する必要があります。セミコロンで区切ったリストは無視されます。
複数のユーザ定義の名前空間が使用される場合の競合を避けるため、名前空間には一意の名前を指定する必要があります。名前空間を匿名にすると、競合が回避されます。
nsref = Namespace( "nsname" | nsref);
名前空間参照を戻します。引数は次のいずれかを取ります。
• 名前空間を含んだ引用符付き文字列
• 名前空間への参照
メモ: Namespace()はすでに存在する名前空間への参照を戻します。新しい名前空間は作成しません。
b = Is Namespace( nsref );
nsrefが名前空間の場合は1(真)、そうでない場合は0(偽)を戻します。
b = As Scoped( "nsname", var_name);
nsname:var_name;
As Scoped()はスコープ参照の関数形です。この関数は、指定の適用範囲にある指定の変数への参照を戻します。
b = Namespace Exists( "nsname" );
nsnameがグローバル名前空間のリスト内に存在する場合は1(真)、そうでない場合は0(偽)を戻します。
Show Namespaces();
グローバル名前空間のリストに含まれるすべての名前空間の中身を表示します。名前空間は、New Namespace関数またはNamespace関数のどちらかを使って参照されるまで表示されません。
名前空間は、管理のための関数だけでなく、その内容にアクセスして操作するための一連のメッセージにも対応します。
これらのメッセージは、他のすべてのメッセージと同様に、スクリプト可能なオブジェクトに送る必要があります。名前空間名は、定義済みのスクリプト可能なオブジェクトではないため、Send操作で使用できません。ただし、名前空間の参照として使用することができます。たとえば、nsmane::varはnsref::varと等価です。
ユーザ定義の名前空間参照でサポートされているメッセージについては、『スクリプト構文リファレンス』の名前空間のメッセージを参照してください。
次に示すものはすべて、nsrefという参照を持つnsnameという名前の名前空間にある、bという名前の変数への参照です。
nsref:b
nsname:b
"nsname":b
nsref["b"]
nsref<<Get Value("b") // 右辺値として使用される
インクルードされたスクリプトは、親スクリプトの名前空間内で実行されます。インクルードされたスクリプトに独自の名前空間が定義されている場合、次のいずれかを行う必要があります。
• 名前の競合を回避するため、名前空間の名前を管理する
• New Namespace関数によって作成される匿名の名前を使用する
どちらの場合も、名前空間への変数参照を管理する必要があります。
Include関数には別のオプション(New Context)があります。これは名前空間を作成し、インクルードされたスクリプトをその中で実行します。この名前空間は匿名で、親スクリプトの名前空間から独立しています。
例:
Include("file.jsl", <<New Context);
この匿名の名前空間は、Hereを使って参照できます。
親と含まれているスクリプトの両方がグローバル名前空間を使用する場合は、名前の競合を避けるために、New ContextオプションにNames Default To Hereを追加します。たとえば、次のような手順で要約できます。
Include("file.jsl", <<New Context, <<Names Default To Here);
Include関数の詳細については、Include(スクリプトを含める)を参照してください。
ここでは、匿名の名前空間を作成し、その中で関数および変数を使用する方法を例示します。
new_emp = New Namespace(
{name_string = "Hello, *NAME*!",
print_greeting = Function( {a},
Print( Substitute( new_emp:name_string, "*NAME*", Char( a ) ) )
)}
);
名前空間内に定義する変数には、必ず完全修飾名を使用します。
new_emp:print_greeting( 6 );
"Hello, 6!"
この例では、まず複素数を表す2元リストをサポートするような関数を含む名前空間を作成し、次にその名前空間をロックします。
If( !Namespace Exists( "complex" ),
New Namespace(
"complex"
);
complex:makec = Function( {a, b},
Eval List( {a, b} )
);
complex:addc = Function( {a, b}, a + b );
complex:subtractc = Function( {a, b}, a - b );
complex:multiplyc = Function( {a, b},
Eval List( {a[1] :* b[1] - a[2] :* b[2], a[1] :* b[2] + a[2] :* b[1]} )
);
complex:dividec = Function( {a, b},
d = b[1] ^ 2 + b[2] ^ 2;
Eval List(
{a[1] :* b[1] - a[2] :* b[2] / d, a[2] :* b[1] - a[1] :* b[2] / d}
);
);
complex:charc = Function( {a},
Char( a[1] ) || "+" || Char( a[2] ) || "i"
);
);
Namespace( "complex" ) << Lock;
次に、このユーザ定義の名前空間に含まれる関数の使用例を示します。
c1 = complex:makec( 3, 4 );
c2 = complex:makec( 5, 6 );
cadd = complex:addc( c1, c2 ); // {8, 10}を戻す
csum = complex:subtractc( c1, c2 ); // {-2, -2}を戻す
cmul = complex:multiplyc( c1, c2 ); // {-9, 38}を戻す
cdiv = complex:dividec( c1, c2 ); // {14.6065573770492, 19.7049180327869}を戻す
Show( complex:charc( c1 ) ); // complex:char(c1) = "3+4i";を戻す
cm1 = complex:makec( [1, 2, 3], [4, 5, 6] ); // {[1, 2, 3], [4, 5, 6]}を戻す