4D ランゲージオブジェクトは、オブジェクト記法を使用して値を設定・取得して管理することができます。互換性上の理由から、この機能を使用するためには明示的に互換性オプションを有効化する必要があります。オブジェクト記法が有効化されると、4D内で式が使用できるところではどこでもオブジェクト記法が使用できるようになります。
オブジェクト記法を通してアクセスされたそれぞれのプロパティ値は式とみなされます。データベース内でオブジェクト記法が有効化されている場合(以下参照)、4D内で式が期待される場所であれば、どこでもこのような値を使用することができます:
- 4Dコード内。メソッド内(メソッドエディター)に書いても、外部化(フォーミュラ、PROCESS 4D TAGS あるいはWeb Server によって処理される4D tags ファイル、4D Write Proドキュメントなど)しても使用可能です。
- デバッガー及びランタイムエクスプローラーの式エリア内。
- フォームエディターのフォームオブジェクトのプロパティリスト内。変数あるいは式フィールド内の他、様々なセレクションリストボックス及びカラム式(データソース、背景色、スタイル、フォントカラー等)において使用可能です。
オブジェクト記法を使用して操作されるオブジェクトは、例えばNew object コマンド等を使用して初期化されている必要があります。そうでない場合、プロパティの読み込みや変更を試みようとするとシンタックスエラーが生成されます。
例:
同じ原理はオブジェクト型のフィールドにも適用されます。:
CREATE RECORD([Person])
[Person]Data_o:=New object
オブジェクト記法を使用すると、トークンのチェーンを通してオブジェクトのプロパティ値やコレクション要素などにアクセスすることができます。
オブジェクト記法では、オブジェクトプロパティは二通りの方法でアクセスすることができます:
- "ドット"記号を使用する方法:
object.propertyName
例:
employee.name:="Smith"
- 大カッコ内の文字列を使用する方法:
object["propertyName"]
例:
$vName:=employee["name"]
オブジェクトプロパティ値にオブジェクトあるいはコレクションを受け取ることが可能なので、オブジェクト記法ではサブプロパティにアクセスするために連続した記号を受け入れることが可能です。例:
$vAge:=employee.children[2].age
オブジェクト記法は、オブジェクトを格納する、あるいはオブジェクトを返すものであれば、どのランゲージ要素でも使用できます。例えば以下のような場所です:
- オブジェクトを返すプロジェクトメソッド
例:
C_OBJECT($0)
$0:=New object("a";10;"b";20)
$result:=MyMethod1.a
コレクション要素にアクセスするためには、大カッコでくくった要素番号を渡す必要があります:
collectionName[expression]
注: コレクション型変数についての詳細な情報については、の章を参照してください。
expression 引数には、正の整数を返す4D 式であれば何でも渡すことができます。例:
myCollection[5]
myCollection[$var]
注: コレクション要素は0から数え始めるという点に注意してください。
オブジェクト記法を使用して、コレクション要素に値を割り当てることもできます:
myCol[10]:="My new element"
この要素インデックスが既存の最後のコレクション要素より大きい場合、コレクションは自動的にリサイズされ、中間の要素には全てnull値が入ります:
Length プロパティ
length プロパティは全てのコレクションに対して設定なしに利用可能なプロパティで、コレクションのサイズ、つまりコレクションが格納している要素の数を返します。このプロパティには二通りの方法でアクセスすることができます:
length プロパティは読み出しのみ可能であり、編集はできないという点に注意してください。
プロパティ値はポインターを通してアクセスすることができます。オブジェクト記法でポインターを使用するのは、オブジェクト記法で直接オブジェクトを使用するのに似ていますが、"ドット"記号は省略する必要があります。
例:
C_OBJECT(vObj)
C_POINTER(vPtr)
vObj:=New object
vObj.a:=10
vPtr:=->vObj
x:=vPtr->a
オブジェクト記法を使用する場合、null 値はNull コマンドを通してサポートされています。このコマンドを使用すると、null 値をオブジェクトプロパティやコレクション要素に割り当てたり、それらと比較したりすることができます。例:
myObject.address.zip:=Null
If(myColl[2]=Null)
詳細な情報については、Null コマンドの説明を参照してください。
オブジェクトプロパティを評価した結果、未定義の値が生成されることがあります。主に未定義の式を読み込み、あるいは割り当てようとしたときに4D はエラーを生成します。ただし以下の場合には生成されません:
- 未定義のオブジェクトプロパティあるいは値を読み込むと未定義が返されます。未定義の値を(配列を除く)変数に割り当てることは、CLEAR VARIABLE コマンドを使うのと同じ効果があります:
C_OBJECT($o)
C_LONGINT($val)
$val:=10
$val:=$o.a
- 未定義のコレクションのlength プロパティを読み込むと0が生成されます:
- 未定義の値を引数としてプロジェクトメソッドに渡した場合、宣言された引数の型に応じて、0あるいは "" (空の文字列)へと自動的に変換されます。
C_OBJECT($o)
mymethod($o.a)
C_TEXT($1)
- 条件式は、If あるいはCase of キーワードで未定義と評価された場合には自動的にfalse へと変換されます:
C_OBJECT($o)
If($o.a)
End if
Case of
:($o.a)
End case
4Dコードの中で特定の型の式が期待される場合、適切な4Dキャストコマンドで囲うことで、たとえ未定義に評価されたとしても適切な型を確実に得ることができます。キャストコマンド: String、Num、Time、Date、Bool。これらのコマンドは式が未定義と評価された場合に、指定された型の空の値を返します。例:
$myString:=Lowercase(String($o.a.b))
Formula あるいは Formula from string メソッドを使用すると、オブジェクトプロパティに格納可能な、ネイティブな"フォーミュラ"オブジェクトを作成することができます:
C_OBJECT($f)
$f:=New object
$f.message:=Formula(ALERT("Hello world"))
このようなプロパティは"オブジェクトメソッド"、つまり親オブジェクトにバインドされているメソッドです。オブジェクトプロパティに保存されているメソッドを実行するには、プロパティ名のあとに( ) 演算子をつけます。例:
$f.message()
大カッコを使用したシンタックスもサポートされます:
$f["message"]()
4D プロジェクトメソッドのように、$1, $2, .... を使用して呼び出すことで、フォーミュラに引数を渡すこともできます:
C_OBJECT($f)
$f:=New object
$f.message:=Formula(ALERT("Hello "+$1))
$f.message("John")
ただし、たとえ引数を受け取らなかったとしても、オブジェクトメソッドを実行するためには() のカッコをつけて呼び出す必要があるという点に注意してください。オブジェクトプロパティのみを呼び出した場合、フォーミュラへの新しい参照が返されます(そしてフォーミュラは実行はされません):
$o:=$f.message
トークンメンバー名(つまりオブジェクト記法を使用してアクセスしたオブジェクトプロパティ名)は、標準の4Dオブジェクト名より厳格な規制があります。これはJavaScript識別子グラマーに則ってなければなりません(ECMA Script standardを参照):
- 1文字目は、文字、アンダースコア(_)、あるいはドル記号($)でなければなりません。
- その後の文字には、文字、数字、あるいはアンダースコアまたはドル記号を使用することができます(スペース文字は使用することはできません)。
- 大文字・小文字は区別されます。
注:
- テーブルフィールドをコレクションインデックスとして使用すること(例: a.b[[Table1]Id] )は許可されていません。この場合には媒介変数を使用する必要があります。
- 大カッコでくくった文字列を使用してオブジェクト属性を作成することで、ECMAスクリプトのルールを上書きすることができます。たとえば$o["My Att.name"] という属性は、スペースを含んではいますが4Dでも有効です。しかしながらこの場合、この属性に対してドット記法を使用することは不可能です。
警告
確かにオブジェクトプロパティは"." または "[ ]" といった特殊文字を含む事は可能(かつ$o["My Att.name"] というシンタックスを使用すればアクセス可能)ですが、これらに対してはクエリや並び替えを実行する事ができないため、推奨されません。dataClass.query( ) や QUERY BY ATTRIBUTE などの、オブジェクトプロパティに対してクエリを実行する全ての4D コマンドやメソッドは、propertyPath または attributePath 引数に文字列を使用します。例えば:
QUERY BY ATTRIBUTE([People];[People]Animals;"dog.name";#;"Rex")
名前に特殊文字を使用しているプロパティを使用したクエリと並び替えは、誤った解釈を起こし得るため、その結果として不正な結果を返す可能性があります。例えば、["A.1.1"]と名前がついたプロパティを定義した場合、以下のようなクエリを実行する事はできません:
QUERY BY ATTRIBUTE([Chapter]];[Chapter]code;"A.1.1";=;"Intro@")
これでまでのどのバージョンにおいても、4Dは常にドット(.)と大カッコ("["および"]")をトクーナイズドされたデータベースオブジェクト名(テーブル、フィールド、変数、メソッド)内にて受け入れてきました。
しかしながら、これらの文字は標準オブジェクト記法においてランゲージトークンを認識するために使用されています。そのため、ドットや大カッコを名前に使用しているデータベースは標準のオブジェクト記法とは相入れません(誤解釈から既存のコードが壊れてしまう可能性があるからです)。例えば、以下のようなコードが書かれていた場合を考えます:
a.b
a.b:=c[1]
...4Dには、a.bとc[1]が、標準の変数名なのか、あるいはbがaというオブジェクトのプロパティで、cがcオブジェクトコレクションの2番目の要素なのかが判別がつけられません。
そのため、以下の点に注意して下さい:
- 4D v17以前のものから変換されたデータベースでは、オブジェクト記法を使用したいということを明示する特定の互換性設定(以下参照)を選択する必要があります。このオプションを選択すると、コードが"オブジェクト記法の用意ができた"ということ、つまり、"." や"[]" 文字を含んでいる名前がデータベース内のどこにも使われていないということを宣言します。
- 特殊なMSC機能により、オブジェクト記法に則っていない名前を検知することができます。オブジェクト記法の有効化の前に、この機能を使用することが強く推奨されます("MSC"の検証ページの章を参照してください)。また、これでまで同様、ストラクチャーファイルのコピーを使用して実行することが推奨されます。
- 4D v17 (v16 R4) 以降、トークナイズされたオブジェクトの名前に"." および"[]" の文字を使用することはできません。
4D v17 以前のバージョンで作成されたデータベースにおいてオブジェクト記法を有効化したい場合、データベース設定ダイアログボックス内の互換性ページにあるオブジェクト記法を使用してオブジェクトプロパティにアクセス(Unicode必須)オプションを選択する必要があります:

この設定についての詳細な情報については、互換性ページを参照してください。
注: コンポーネントについては、ホストデータベースと異なる設定を持つことができます。
オブジェクト記法を使用すると、オブジェクトを扱う際の4Dコードを単純化することができます。しかしながら、コマンドベースの記法は引き続き完全にサポートされているという点に注意して下さい。
- オブジェクトの読み書きについて(この例題ではオブジェクト記法とコマンド記法を比較します):
C_OBJECT($myObj)
$myObj:=OB New
$myObj.age:=56
$age:=$myObj.age
C_OBJECT($myObj2)
OB SET($myObj2;"age";42)
$age:=OB Get($myObj2;"age")
C_OBJECT($myObj3)
OB SET($myObj3;"age";10)
$age:=$myObj3.age
- プロパティを作成し、オブジェクトを含む値を割り当てる:
C_OBJECT($Emp)
$Emp:=New object
$Emp.city:="London"
$Emp.city:="Paris"
$Emp.phone:=New object("office";"123456789";"home";"0011223344")
- オブジェクト記法を使用すると、サブオブジェクトの値を取得するのも容易になります:
$vCity:=$Emp.city
$vPhone:=$Emp.phone.home
- [ ] 演算子を使用するとプロパティに文字列としてアクセスできます。
$Emp["city"]:="Berlin"
C_TEXT($addr)
$addr:="address"
For($i;1;4)
$Emp[$addr+String($i)]:=""
End for