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

Object

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

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

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

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

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

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

caution

プロパティ名は大文字と小文字を区別するという点に注意してください。

オブジェクト型の変数・フィールド・式を操作するには オブジェクト記法 を用いるか、オブジェクト (ランゲージ) テーマが提供するコマンドを使用します。

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

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

インスタンス化

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

オブジェクトのインスタンス化は、以下のいずれかの方法でおこなうことができます:

  • New object コマンドを使用する。
  • {} 演算子を使用する。
info

いくつかの 4Dコマンドや関数はオブジェクトを返します。たとえば、Database measuresFile などです。 この場合、オブジェクトを明示的にインスタンス化する必要はなく、4Dランゲージが代わりにおこなってくれます。 この場合、オブジェクトを明示的にインスタンス化する必要はなく、4Dランゲージが代わりにおこなってくれます。

New object コマンド

New object コマンドは、空の、あるいは値の入った新規コレクションを作成し、その参照を返します。

例:

 var $obVar : Object // オブジェクト型 4D変数の宣言
$obVar:=New object // オブジェクトのインスタンス化と 4D変数への代入

var $obFilled : Object
$obFilled:=New object("name"; "Smith"; "age";42) // プロパティが格納されたオブジェクトのインスタンス化と変数への代入

{} 演算子

{} 演算子を使って、オブジェクトリテラル を作成することができます。 オブジェクトリテラルとは、オブジェクトのプロパティ名とその値のペアが 0組以上含まれたセミコロン区切りのリストを中括弧 {} で囲んだものです。 オブジェクトリテラルのシンタックスは、空の、またはプロパティが格納されたオブジェクトを作成します。

プロパティの値は式とみなされるため、プロパティ値に {} を使ってサブオブジェクトを作成することができます。 また、コレクションリテラル を作成し、参照することもできます。 また、コレクションリテラル を作成し、参照することもできます。

例:

 var $o ; $o2 ; $o3 : Object // オブジェクト変数の宣言
$o := {} // 空のオブジェクトのインスタンス化
$o2 := {a: "foo"; b: 42; c: {}; d: ($toto) ? true : false } // プロパティを格納したオブジェクトのインスタンス化
// オブジェクト: {"a":"foo","b":42,"c":{},"d":false}

// 変数を使っても同様にオブジェクトをインスタンス化できます
var $a : Text
var $b : Number
var $c : Object
$a:="foo"
$b:=42
$c:={}
$o3:={ a: $a; b: $b; c: $c } // {"a":"foo";b":42;"c":{}}

New object とリテラルを使ったシンタックスは混在させることができます:

$o:={\
ob1: {age: 42}; \
ob2: New object("message"; "Hello"); \
form1: Formula(return This.ob1.age+10); \
form2 : Formula(ALERT($1)); \
col: [1; 2; 3; 4; 5; 6]\
}

$o.form1() // 52
$o.form2($o.ob2.message) // Hello と表示します
$col:=$o.col[5] // 6

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

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

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

Assignment

Object and collection data types are handled in the 4D language through references (i.e., internal pointers), unlike scalar data types (integer, date, etc.). As a result, when assigning an object or a collection to a variable (e.g. $myVar:={ a:2 }), it is the reference that is assigned, not the value itself. Any subsequent modification of the $myVar variable will therefore be reflected everywhere the original object is referenced. This follows the same principle as pointers, except that the $myVar variable does not need to be dereferenced.

例:

var $o1; $o2 : Object
var $col : Collection

$col:=[1;2;3] //a reference to the collection is created
$o1:={ a:2 ; b:$col } //a reference to the object is created
$o2:=$o1 //both variables $o1 and $o2 share the reference to the same object

$o1.a:=10 //$o2 = {"a":10,"b":[1,2,3]}
$o2.a:=20 //$o1 = {"a":20,"b":[1,2,3]}
$col.push(4)
//$o1 = {"a":20,"b":[1,2,3,4]}
//$o2 = {"a":20,"b":[1,2,3,4]}
ASSERT($o1=$o2) //True

This principle applies wherever objects or collections are used, including in parameters or formula expressions.

If you want to create a deep copy of an object, use the OB COPY command.

プロパティ

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

  • "ドット"記号を使用する方法:

    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:=Database measures.DB.tables
  • オブジェクトを返す プロジェクトメソッド または 関数。 例: 例:
      // MyMethod1
#DECLARE -> $o : Object
$o:=New object("a";10;"b";20)

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

Null 値

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

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

詳細については Null と 未定義 を参照ください。

未定義の値

オブジェクトプロパティを評価した結果、未定義の値が生成されることがあります。 未定義の値を存在しないオブジェクトのプロパティへと代入した場合は、何も起こりません。 未定義の値を既存のオブジェクトプロパティに代入した場合、その値は初期化、あるいは消去されます。

詳細については Null と 未定義 を参照ください。

ポインター

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

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

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

pointerOnObject->propertyName

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

pointerOnObject->["propertyName"]

例:

 var vObj : Object
var vPtr : Pointer
vObj:=New object
vObj.a:=10
vPtr:=->vObj
x:=vPtr->a //x=10

オブジェクト演算子

オブジェクト参照 に対して比較演算子を使用することができます。つまり、2つ以上の参照が同じオブジェクトのインスタンスを指しているかどうかを評価することができます。

var $o1:={a: 42} // とあるインスタンスへの参照
var $o2:={a: 42} // 異なるインスタンスへの参照
var $o3:=$o1 // 同じインスタンスへの参照

上のコードに基づいて、比較表は次のようになります:

演算シンタックス戻り値
等しいobjectRef = objectRefBoolean$o1 = $o3true
$o1 = $o2false
異なるobjectRef # objectRefBoolean$o1 # $o3false
$o1 # $o2true

Resources

オブジェクトは、ドキュメント、エンティティロック、そしてメモリなどの リソース を使用します。 オブジェクトが必要とする限り、これらのリソースは保持されます。 変数や他のオブジェクトから参照されなくなったことを検知すると、4D はその参照されなくなったオブジェクトが使用していたリソースをすべて自動的に解放するため、通常はこの処理を意識することはありません。

たとえば、$entity.lock() でロックしたエンティティへの参照がなくなると、4D はメモリを解放すると同時に、関連するロックも自動で解放するため、$entity.unlock() の呼び出しは不要です。

オブジェクトが占有しているすべてのリソースについて、4D による自動解放 (メソッド実行終了時のローカル変数など) を待たずに、すぐに解放したい場合、オブジェクトの 参照をすべて無効化 することができます。 例: 例: 例: 例:


$doc:=WP Import document("large_novel.4wp")
... // $doc に対する処理
$doc:=Null // $docが占有するリソースを解放します
... // 増えた空きメモリで実行を継続します

クラス

オブジェクトは特定のクラスに所属することができます。 オブジェクトは特定のクラスに所属することができます。 クラスを使用することで、オブジェクトの振る舞いと構造を、関連するプロパティと関数で事前に定義することができます。

4D ランゲージでは、オブジェクトを管理するための複数の ネイティブなクラス が提供されています。 またコードを整理するために独自の ユーザークラス を定義して使用することもできます。 またコードを整理するために独自の ユーザークラス を定義して使用することもできます。

ストリーミングサポート

ストリーム可能なクラス(または シリアライズ可能な クラス)とは、そのオブジェクトを連続したバイト(テキストまたはバイト)へと変換可能なクラスのことであり、これによってオブジェクトをファイルに書き込んだり、引数として送信したり、あるいは後で再構築できるように保存できるようなクラスをさします。

テキストストリーミング(JSON Stringify)

JSON Stringify などの、コンテンツを文字列化するJSON コマンドと Execute on server コマンドを使用することで、オブジェクトをJSON (テキスト)へと変換することができます。 これらのコマンドはオブジェクト、コレクション、そしてユーザークラスをサポートします。 これらのコマンドはオブジェクト、コレクション、そしてユーザークラスをサポートします。

しかしながら、オブジェクトのテキストストリーミングには、以下の様な制約があります:

  • 循環参照(自分自身をプロパティとして格納してるオブジェクト)はサポートされおらず、エラーを返します
  • クラスのオブジェクトは文字列化した際にどのクラスであるかという情報は失われます
  • Entity などのネイティブな4D クラスオブジェクトはJSON として表現はできず、"[object <class>]" と返されます。例: "[object Entity]"

バイナリーストリーミング(VARIABLE TO BLOB)

4D では、 VARIABLE TO BLOB コマンドを通して、ビルトインのバイナリーストリーミング機能を実装しています。 この機能を使用することで、テキストストリーミングにおける制約の大部分を回避することができます(上記参照): この機能を使用することで、テキストストリーミングにおける制約の大部分を回避することができます(上記参照):

  • 循環参照はサポートされます
  • オブジェクトはどのクラスであるかを維持します
  • 幅広いタイプのオブジェクトがストリーム可能です: 4D Write Pro ドキュメント、オブジェクトのピクチャー、オブジェクトのBLOB、およびオブジェクトのポインターなど
  • いくつかのネイティブな4D クラスオブジェクトもストリーム可能です。例えば、 FileFolder、あるいは Vector など。 しかしながら、ストリーム可能なネイティブ4D クラスは限られています。 明示的に"このクラスはバイナリー形式で ストリーム可能 です" と明示されていない限り、そのネイティブ4D クラスはストリーム可能ではないものだと考えてください。 しかしながら、ストリーム可能なネイティブ4D クラスは限られています。 明示的に"このクラスはバイナリー形式で ストリーム可能 です" と明示されていない限り、そのネイティブ4D クラスはストリーム可能ではないものだと考えてください。

例題

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

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

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

// もちろん両方の記法を混用することもできます
var $myObj3 : Object
OB SET($myObj3;"age";10)
$age:=$myObj3.age // 10
  • プロパティの作成と、オブジェクトを含む値の代入:
 var $Emp : Object
$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 プロパティを変更
// これは変数を通してプロパティを作成する場合に便利です
var $addr : Text
$addr:="address"
For($i;1;4)
$Emp[$addr+String($i)]:=""
End for
/// $Emp object には 4つの空のプロパティ "address1...address4" が作成されました