メインコンテンツまでスキップ
バージョン: 19

オブジェクト

オブジェクト型の変数・フィールド・式にはさまざまなデータを格納することができます。 4D のネイティブなオブジェクトの構造は、よくある「プロパティ/値」(または「属性/値」) というペア (連想配列) に基づいています。 これらオブジェクトの記法は JSON をもとにしていますが、完全に同じというわけではありません。

  • プロパティ名は必ずテキストで表現されます。 プロパティ名には 命名規則 があります。

  • プロパティ値は以下のどれかの型で表現されます:

    • 数値 (実数、整数、等)
    • テキスト
    • null
    • ブール
    • ポインター (JSON Stringify コマンドの使用、またはコピーの際に評価されます)
    • 日付 (日付型あるいは ISO日付フォーマット文字列)
    • オブジェクト(1) (オブジェクトは入れ子にすることができます)
    • ピクチャー(2)
    • コレクション

(1) ORDAオブジェクト (エンティティエンティティセレクション 等)、Webサーバーオブジェクト などの ストリームできないオブジェクトオブジェクトフィールド には保存できません。 保存しようとするとエラーが返されます。しかし、メモリ内の オブジェクト変数 に保存することは可能です。

(2) デバッガー内でテキストとして表示したり、JSON へと書き出されたりした場合、ピクチャー型のオブジェクトプロパティは "[object Picture]" と表されます。

警告: 属性名は大文字と小文字を区別するという点に注意してください。

オブジェクト型の変数・フィールド・式を操作するには オブジェクト記法 を用いるか、オブジェクト (ランゲージ) テーマが提供する従来のコマンドを使用します。 オブジェクト型フィールドに対して処理をおこなうには QUERY BY ATTRIBUTEQUERY SELECTION BY ATTRIBUTEORDER BY ATTRIBUTE など、クエリ テーマの特定のコマンドも使用することができます。

オブジェクト記法を使ってアクセスされたそれぞれのプロパティ値は式とみなされます。 4D内で式が期待される場所であれば、どこでもこのような値を使用することができます:

  • 4Dコード内。メソッド (メソッドエディター) に書いても、外部化(フォーミュラ、PROCESS 4D TAGS あるいは Web Server によって処理される 4D tags ファイル、4D Write Proドキュメントなど) しても使用可能です。
  • デバッガー及びランタイムエクスプローラーの式エリア内。
  • フォームエディターにおいて、フォームオブジェクトのプロパティリスト内。変数あるいは式フィールド内の他、様々なセレクションリストボックス及びカラムの式 (データソース、背景色、スタイル、フォントカラー等) において使用可能です。

初期化

New object コマンドを使うなどして、オブジェクトはあらかじめ初期化しておく必要があります。初期化しない場合、プロパティ値の取得や変更はシンタックスエラーとなります。

例:

 C_OBJECT($obVar) // オブジェクト型の変数の作成
$obVar:=New object // オブジェクトの初期化と変数への代入

通常オブジェクトと共有オブジェクト

二種類のオブジェクトを作成することができます:

  • New object コマンドを使用して作成する通常 (非共有) オブジェクト。 通常のオブジェクトは特別なアクセスコントロールをせずに編集可能ですが、プロセス間で共有することはできません。
  • New shared object コマンドを使用して作成する共有オブジェクト。 共有オブジェクトはプロセス間 (プリエンティブ・スレッド含む) で共有可能なオブジェクトです。 共有オブジェクトへのアクセスは Use...End use 構造によって管理されています。 詳細な情報については、共有オブジェクトと共有コレクション を参照ください。

オブジェクト記法の使用

オブジェクト記法を使うと、トークンのチェーンを通してオブジェクトのプロパティ値にアクセスすることができます。

オブジェクトプロパティ

オブジェクト記法では、オブジェクトプロパティは二通りの方法でアクセスすることができます:

  • "ドット" 記号を使用する方法: > object.propertyName

例:

     employee.name:="Smith"
  • 大カッコと文字列を使用する方法: > object["propertyName"]

例:

     $vName:=employee["name"]
// または:
$property:="name"
$vName:=employee[$property]

オブジェクトプロパティ値には、オブジェクトやコレクションも設定することが可能です。これらのサブプロパティにアクセスするため、オブジェクト記法では連続した字句を受け入れることができます:

 $vAge:=employee.children[2].age

オブジェクトを格納、あるいは返すあらゆるランゲージ要素に対してオブジェクト記法を使用できます。たとえば:

  • オブジェクト 自身 (変数、フィールド、オブジェクトプロパティ、オブジェクト配列、コレクション要素などに保存されているもの)。 例:
     $age:=$myObjVar.employee.age // 変数
$addr:=[Emp]data_obj.address // フィールド
$city:=$addr.city // オブジェクトプロパティ
$pop:=$aObjCountries{2}.population // オブジェクト配列
$val:=$myCollection[3].subvalue // コレクション要素
  • オブジェクトを返す 4D コマンド。 例:
     $measures:=Get database measures.DB.tables
  • オブジェクトを返す プロジェクトメソッド 例:
      // MyMethod1
C_OBJECT($0)
$0:=New object("a";10;"b";20)

//myMethod2
$result:=MyMethod1.a //10
  • コレクション。 例:
     myColl.length // コレクションの長さ

ポインター

注: オブジェクトは常に参照として渡されるため、通常はポインターを使用する必要はありません。 オブジェクトを引数として渡す際、4D 内部では自動的にポインターに類似したメカニズムを使うことでメモリの消費を最小限に抑え、引数を編集して返すことを可能にします。 つまり、ポインターは必要ないということです。 それでもポインターを使用したい場合には、プロパティ値はポインターを通してアクセスすることができます。

ポインターを使ってオブジェクトプロパティにアクセスするには、直接オブジェクトを使用する場合と方法が似ていますが、"ドット" 記号は省略する必要があります。

  • オブジェクト記法によるアクセス:

pointerOnObject->propertyName

  • 大カッコを使用する方法:

pointerOnObject->["propertyName"]

例:

 C_OBJECT(vObj)
C_POINTER(vPtr)
vObj:=New object
vObj.a:=10
vPtr:=->vObj
x:=vPtr->a //x=10

Null 値

オブジェクト記法を使用する場合、null 値は Null コマンドを通してサポートされています。 このコマンドを使用すると、null 値をオブジェクトプロパティやコレクション要素に割り当てたり、それらと比較したりすることができます。例:

 myObject.address.zip:=Null
If(myColl[2]=Null)

詳細については、Null コマンドの説明を参照してください。

未定義の値

オブジェクトプロパティを評価した結果、未定義の値が生成されることがあります。 未定義の式を読み込んだ、または割り当てようとしたときに 4D は通常、エラーを生成します。 ただし以下の場合には生成されません:

  • 未定義のオブジェクトやプロパティ値を読み込むと未定義 (undefined) が返されます。未定義の値を (配列を除く) 変数に割り当てることは、CLEAR VARIABLE コマンドを使うのと同じ効果があります:
     C_OBJECT($o)
C_LONGINT($val)
$val:=10 //$val=10
$val:=$o.a // $o.a は未定義 (エラーなし) なため、この値を代入すると変数が初期化されます
// $val=0
  • 未定義のコレクションの length プロパティは 0 を返します:
     C_COLLECTION($c) // 変数は作成されたが、コレクションは未定義     $size:=$c.length // $size = 0
  • 未定義の値を引数としてプロジェクトメソッドに渡した場合、宣言された引数の型に応じて、0 あるいは "" (空の文字列) へと自動変換されます。
     C_OBJECT($o)
mymethod($o.a) // 未定義の引数を渡すと

// mymethod メソッド内では
C_TEXT($1) // 引数の型はテキスト
// $1 の中身は""
  • 条件式で、If あるいは Case of キーワードで未定義と評価された場合には、自動的にfalse へと変換されます:
     C_OBJECT($o)
If($o.a) // false
End if
Case of
:($o.a) // false
End case
  • 未定義の値を既存のオブジェクトプロパティに代入した場合、その値は型に応じて初期化、あるいは消去されます:
  • オブジェクト、コレクション、ポインター: Null
  • ピクチャー: 空のピクチャー
  • ブール: False
  • 文字列: ""
  • 数値: 0
  • 日付: "オブジェクトではISO日付フォーマットの代わりに日付型を使用する" 設定が有効化されている場合は !00-00-00!、それ以外の場合には ""
  • 時間: 0 (ミリ秒単位)
  • 未定義、Null: 変化なし
     C_OBJECT($o)
$o:=New object("a";2)
$o.a:=$o.b // $o.a=0
  • 未定義の値を存在しないオブジェクトのプロパティへと代入した場合は、何も起こりません。

4Dコード内の式に対して特定の型であることが要求される場合、その式を適切な 4Dキャストコマンド (String, Num, Date, Time, Bool) で囲うことで、たとえ未定義に評価されたとしても正しい型を確実に得ることができます。 これらのコマンドは式が未定義と評価された場合に、指定された型の空の値を返します。 例:

 $myString:=Lowercase(String($o.a.b)) // 未定義の場合でもコード内でエラーが起きないように
// 文字列の値が得られるようにします

例題

オブジェクト記法を使用すると、オブジェクトを扱う際の 4Dコードを単純化することができます。 同時に、コマンドベースの記法も引き続き完全にサポートされています。

  • オブジェクトの読み書き (この例題ではオブジェクト記法とコマンド記法を比較します):
  // オブジェクト記法を使用
C_OBJECT($myObj) // 4Dオブジェクト変数を宣言
$myObj:=New object // オブジェクト作成し、変数に代入
$myObj.age:=56
$age:=$myObj.age // 56

// コマンド記法を使用
C_OBJECT($myObj2) // 4Dオブジェクト変数を宣言
OB SET($myObj2;"age";42) // オブジェクトを作成し、ageプロパティを追加
$age:=OB Get($myObj2;"age") // 42

// もちろん両方の記法を混用することもできます
C_OBJECT($myObj3)
OB SET($myObj3;"age";10)
$age:=$myObj3.age // 10
  • プロパティの作成と、オブジェクトを含む値の代入:
 C_OBJECT($Emp)
$Emp:=New object
$Emp.city:="London" // cityプロパティを作成し、その値を"London"に設定します
$Emp.city:="Paris" // cityプロパティを変更します
$Emp.phone:=New object("office";"123456789";"home";"0011223344")
// phoneプロパティを作成し、その値にオブジェクトを設定します
  • オブジェクト記法を使用すると、サブオブジェクトの値を簡単に取得できます:
 $vCity:=$Emp.city // "Paris"
$vPhone:=$Emp.phone.home // "0011223344"
  • 大カッコ [ ] を使用すると文字列を使ってプロパティにアクセスできます:
 $Emp["city"]:="Berlin" // city プロパティを変更
// これは変数を通してプロパティを作成する場合に便利です
C_TEXT($addr)
$addr:="address"
For($i;1;4)
$Emp[$addr+String($i)]:=""
End for
// $Emp object には4つの空のプロパティ "address1...address4" が作成されました