内部で保持されている名前テーブル(シンボルテーブル)で、myVar が検索されます。
ColdFusion では、構造体、クエリ、XML ドキュメントオブジェクト、外部オブジェクトなどの複合変数の各要素は、ピリオド(.)を使用して区切ります。例えば、MyStruct.KeyName のようにします。また、変数名と変数スコープ識別子を区切るときにもピリオドを使用します。例えば、Variables.myVariable や CGI.HTTP_COOKIE のようにします。
Cookie および Client スコープの変数(これらは常に単純変数型になります)を除き、通常は、単純変数の名前にピリオドを含めることはできません。ただし、この要件を満たしていないレガシーコードやサードパーティコードに対応できるように、いくつかの例外が設けられています。
詳細については、スコープについて、配列および構造体の使用および XML および WDDX の使用を参照してください。
変数とピリオドについて
次のセクションでは、MyVar.a.b という変数を例に取って、ColdFusion で変数値を取得および設定するときのピリオドの使用方法について説明します。
変数の取得
ColdFusion では、変数の名前にピリオドが含まれていても、変数の値を正しく取得できます。例えば、<cfset Var2 = myVar.a.b> や IsDefined(myVar.a.b) という式では、次の手順に従って MyVar.a.b が取得されます。
-
-
myVar が複合オブジェクト(スコープを含む)の名前である場合は、オブジェクト内の「a」という要素が検索されます。myVar が複合オブジェクトの名前でない場合は、myVar.a が複合オブジェクトの名前であるかどうかが確認され、手順 3 が省略されます。
-
myVar が複合オブジェクトの名前である場合は、a が複合オブジェクトであるかどうかが確認されます。
-
If a または myVar.a が複合オブジェクトの名前である場合は、b が単純変数の名前であるかどうかが確認され、b の値が返されます。myVar が複合オブジェクトであり、a が複合オブジェクトでない場合は、a.b が単純変数の名前であるかどうかが確認され、その値が返されます。myVar.a が複合オブジェクトでない場合は、myVar.a.b が単純変数の名前であるかどうかが確認され、その値が返されます。
このようにして変数名が正しく解決され、その値が取得されます。
名前にピリオドが含まれている単純変数は、配列表記を使用して取得することもできます。この配列表記では、スコープ名(または単純変数が含まれている複合変数)を配列名として使用します。角括弧の中では、単純変数の名前を単一引用符(')または二重引用符(")で囲んで記述します。
配列表記では、キーの可能な組み合わせを ColdFusion が解析して確認する必要がないので、通常のドット表記よりも効率的です。例えば、次の行はどちらも myVar.a.b の値を出力しますが、2 番目のほうが効率的です。
<cfoutput>myVar.a.b is: #myVar.a.b#<br></cfoutput> <cfoutput>myVar.a.b is: #Variables["myVar.a.b"]#<br></cfoutput>
変数の設定
変数値を設定する場合は、変数を取得するときのような柔軟性はありません。これは、作成または設定する変数の型を決定する必要があるからです。したがって、設定する変数名のルールはより厳格になります。このルールは、変数名の最初の部分が Cookie または Client スコープ識別子であるかどうかによって異なります。
例えば、次のコードがあるとします。
<cfset myVar.a.b = "This is a test">
変数 myVar が存在していない場合は、次の処理が行われます。
-
myVar という構造体が作成されます。
-
構造体 myVar の中に a という 構造体が作成されます。
-
myVar.a の中に b というキーが作成されます。
-
このキーに "これはテストです" という値が設定されます。
myVar または myVar.a が存在し、そのいずれも構造体でない場合は、エラーになります。
つまり、変数を取得するときと同じルールを使用して、まだ存在しない名前が検出されるまで変数名が解析されます。次に、b というキーを内部に作成するために必要な構造体が作成され 、 そのキーに値が割り当てられます。
ただし、最初のピリオドの前にある名前が Cookie、Client、ColdFusion のいずれかである場合は、別のルールが使用されます。この場合は、スコープ名の後に続くすべてのテキスト(ピリオドも含む)が、単純変数の名前と見なされます。 これは、 Cookie および Client スコープの変数が常に単純変数だからです。次のコードを実行すると、myVar.a.b という名前の Client スコープの単純変数が 1 つ作成されます。
<cfdump var=#Client.myVar.a.b#>
ピリオドを持つ変数の作成
構造体のドット表記を除き、ピリオドを含んだ変数名は作成しないでください。ただし、外部データソースの変数名との互換性の維持や、変数名にピリオドを使用している既存のコードの統合など、ピリオドの使用を避けられない場合に、これを処理するためのメカニズムが用意されています。次のセクションでは、ピリオドを含んだ単純変数名を作成する方法について説明します。
括弧を使用してピリオドを持つ変数を作成する
<cfscript> Request["Another.Variable.With.Periods"] = "Test variable"; writeOutput("My.Variable.With.Periods is: #My.Variable.With.Periods# Request.Another.Variable.With.Periods is: #Request.Another.Variable.With.Periods#"); </cfscript>
ピリオドを持つ Client および Cookie 変数の作成
ピリオドを含んだ Client または Cookie 変数を作成するには、単純にその変数に値を代入します。例えば次の行では、User.Preferences.CreditCard という Cookie が作成されます。
<cfset Cookie.User.Preferences.CreditCard="Discover">
セーフナビゲーション演算子の使用
ColdFusion の 2016 リリースには、構造体のメンバーまたはオブジェクトの値にアクセスするためにセーフナビゲーション演算子(?.)が導入されています。
「.」ではなく、セーフ演算子を使用すると、変数が定義されていない場合でも例外がスローされません。
ColdFusion(2016 リリース)では、セーフナビゲーションを次のように使用できます。
writeOutput( myvar ?.firstlevel?.nextlevel?.udf()?.trim());
フック演算子(「?」)をピリオド演算子(「.」)と組み合わせて使用すると、セーフナビゲーション演算子(「?.」)になります。
定義されていない変数、つまり値が Java null の変数を使用した場合は、エラーが発生する代わりに、その特定のアクセスについてセーフナビゲーション演算子の戻り値が不定になります。 そうでない場合は、
ピリオド(「.」)演算子とまったく動作になります。
例えば、変数 myvar が定義されていない場合、myvar?.firstlevel の戻り値は不定になります。定義されている場合は、「myvar.firstlevel」の値を返します。
セーフナビゲーションは、関数呼び出し、構造体アクセスまたはその両方で使用できます。
関数の呼び出し時にセーフナビゲーション演算子を使用すると、次の場合に戻り値が不定になります。
- 関数でエラーが発生する
- 関数が存在しない
それ以外の場合は、ピリオド(「.」)演算子とまったく動作になります。
セーフナビゲーション演算子では、未定義変数、null 変数、関数呼び出しのエラーなどを処理できます。この演算子を使用すると、ランタイムエラーがスキップされます。