ここは旧式の4DドキュメントWebサイトです。最新のアップデートされたドキュメントを読むには新サイトをご利用下さい→ developer.4d.com

ホーム

 
4D v19.8
オブジェクト記法の使用

オブジェクト記法の使用  


 

概要  

4D ランゲージオブジェクトは、オブジェクト記法を使用して値を設定・取得して管理することができます。互換性上の理由から、この機能を使用するためには明示的に互換性オプションを有効化する必要があります。オブジェクト記法が有効化されると、4D内で式が使用できるところではどこでもオブジェクト記法が使用できるようになります。

オブジェクト記法を通してアクセスされたそれぞれのプロパティ値はとみなされます。データベース内でオブジェクト記法が有効化されている場合(以下参照)、4D内でが期待される場所であれば、どこでもこのような値を使用することができます:

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

オブジェクト記法を使用して操作されるオブジェクトは、例えばNew object コマンド等を使用して初期化されている必要があります。そうでない場合、プロパティの読み込みや変更を試みようとするとシンタックスエラーが生成されます。

例:

 C_OBJECT($obVar//オブジェクト型の4D変数の作成
 $obVar:=New object //オブジェクトの初期化と4D変数への割り当て

同じ原理はオブジェクト型のフィールドにも適用されます。:

 CREATE RECORD([Person]) //オブジェクトフィールドを含むテーブルに新しいレコードを追加
 [Person]Data_o:=New object //オブジェクトの初期化と4Dフィールドへの割り当て

概要  

オブジェクト記法を使用すると、トークンのチェーンを通してオブジェクトのプロパティ値やコレクション要素などにアクセスすることができます。

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

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

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

    例:
     $vName:=employee["name"]

オブジェクトプロパティ値にオブジェクトあるいはコレクションを受け取ることが可能なので、オブジェクト記法ではサブプロパティにアクセスするために連続した記号を受け入れることが可能です。例:

 $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 //コレクションのサイズ
     maxSal:=myColl.max("salary")

コレクション要素にアクセスするためには、大カッコでくくった要素番号を渡す必要があります:

collectionName[expression]

注: コレクション型変数についての詳細な情報については、の章を参照してください。

expression 引数には、正の整数を返す4D 式であれば何でも渡すことができます。例:

 myCollection[5]  //コレクションの第6要素にアクセス
 myCollection[$var]

注: コレクション要素は0から数え始めるという点に注意してください。

オブジェクト記法を使用して、コレクション要素に値を割り当てることもできます:

 myCol[10]:="My new element"

この要素インデックスが既存の最後のコレクション要素より大きい場合、コレクションは自動的にリサイズされ、中間の要素には全てnull値が入ります:

 C_COLLECTION(myCol)
 myCol:=New collection("A";"B")
 myCol[5]:="Z"
  //myCol[2]=null
  //myCol[3]=null
  //myCol[4]=null

Length プロパティ

length プロパティは全てのコレクションに対して設定なしに利用可能なプロパティで、コレクションのサイズ、つまりコレクションが格納している要素の数を返します。このプロパティには二通りの方法でアクセスすることができます:

  • "ドット"記号を使用する。例:
     $vSize:=myCollection.length
  • 大カッコでくくられた文字列を使用する。例:
     $vSize:=myCollection["length"]
length プロパティは読み出しのみ可能であり、編集はできないという点に注意してください。

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

  • トークンでのアクセス:
    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 値をオブジェクトプロパティやコレクション要素に割り当てたり、それらと比較したりすることができます。例:

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

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

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

  • 未定義のオブジェクトプロパティあるいは値を読み込むと未定義が返されます。未定義の値を(配列を除く)変数に割り当てることは、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キャストコマンドで囲うことで、たとえ未定義に評価されたとしても適切な型を確実に得ることができます。キャストコマンド: StringNumTimeDateBool。これらのコマンドは式が未定義と評価された場合に、指定された型の空の値を返します。例:

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

Formula あるいは Formula from string メソッドを使用すると、オブジェクトプロパティに格納可能な、ネイティブな"フォーミュラ"オブジェクトを作成することができます:

 C_OBJECT($f)
 $f:=New object
 $f.message:=Formula(ALERT("Hello world"))

このようなプロパティは"オブジェクトメソッド"、つまり親オブジェクトにバインドされているメソッドです。オブジェクトプロパティに保存されているメソッドを実行するには、プロパティ名のあとに( ) 演算子をつけます。例:

 $f.message() // "Hello world" を表示する

大カッコを使用したシンタックスもサポートされます:

 $f["message"]() // "Hello world" を表示する

4D プロジェクトメソッドのように、$1, $2, .... を使用して呼び出すことで、フォーミュラに引数を渡すこともできます:

 C_OBJECT($f)
 $f:=New object
 $f.message:=Formula(ALERT("Hello "+$1))
 $f.message("John") // "Hello John" と表示

ただし、たとえ引数を受け取らなかったとしても、オブジェクトメソッドを実行するためには() のカッコをつけて呼び出す必要があるという点に注意してください。オブジェクトプロパティのみを呼び出した場合、フォーミュラへの新しい参照が返されます(そしてフォーミュラは実行はされません):

 $o:=$f.message //$o にフォーミュラオブジェクトが返される

トークンメンバー名(つまりオブジェクト記法を使用してアクセスしたオブジェクトプロパティ名)は、標準の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") //dog のサブプロパティ

名前に特殊文字を使用しているプロパティを使用したクエリと並び替えは、誤った解釈を起こし得るため、その結果として不正な結果を返す可能性があります。例えば、["A.1.1"]と名前がついたプロパティを定義した場合、以下のようなクエリを実行する事はできません:

 QUERY BY ATTRIBUTE([Chapter]];[Chapter]code;"A.1.1";=;"Intro@") //この場合プロパティ名はパスとして解釈されてしまう

これでまでのどのバージョンにおいても、4Dは常にドット(.)と大カッコ("["および"]")をトクーナイズドされたデータベースオブジェクト名(テーブル、フィールド、変数、メソッド)内にて受け入れてきました。

しかしながら、これらの文字は標準オブジェクト記法においてランゲージトークンを認識するために使用されています。そのため、ドットや大カッコを名前に使用しているデータベースは標準のオブジェクト記法とは相入れません(誤解釈から既存のコードが壊れてしまう可能性があるからです)。例えば、以下のようなコードが書かれていた場合を考えます:

a.b
a.b:=c[1]

...4Dには、a.bc[1]が、標準の変数名なのか、あるいはbaというオブジェクトのプロパティで、ccオブジェクトコレクションの2番目の要素なのかが判別がつけられません。

そのため、以下の点に注意して下さい:

  • 4D v17以前のものから変換されたデータベースでは、オブジェクト記法を使用したいということを明示する特定の互換性設定(以下参照)を選択する必要があります。このオプションを選択すると、コードが"オブジェクト記法の用意ができた"ということ、つまり、"." や"[]" 文字を含んでいる名前がデータベース内のどこにも使われていないということを宣言します。
  • 特殊なMSC機能により、オブジェクト記法に則っていない名前を検知することができます。オブジェクト記法の有効化の前に、この機能を使用することが強く推奨されます("MSC"の検証ページの章を参照してください)。また、これでまで同様、ストラクチャーファイルのコピーを使用して実行することが推奨されます。
  • 4D v17 (v16 R4) 以降、トークナイズされたオブジェクトの名前に"." および"[]" の文字を使用することはできません。

4D v17 以前のバージョンで作成されたデータベースにおいてオブジェクト記法を有効化したい場合、データベース設定ダイアログボックス内の互換性ページにあるオブジェクト記法を使用してオブジェクトプロパティにアクセス(Unicode必須)オプションを選択する必要があります:

この設定についての詳細な情報については、互換性ページを参照してください。

注: コンポーネントについては、ホストデータベースと異なる設定を持つことができます。

 

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

  • オブジェクトの読み書きについて(この例題ではオブジェクト記法とコマンド記法を比較します):

  // オブジェクト記法を使用
 C_OBJECT($myObj//4Dオブジェクト変数を宣言
 $myObj:=OB New //オブジェクト作成し、変数に割り当てる
 $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" が作成されました



参照 

C_COLLECTION
C_OBJECT
New collection
New object
オブジェクト記法解析エラー (-10737 -> -10701)

 
プロパティ 

プロダクト: 4D
テーマ: オブジェクト(ランゲージ)

 
ページの目次 
 
履歴 

初出: 4D v16 R4

 
ARTICLE USAGE

ランゲージリファレンス ( 4D v19)
ランゲージリファレンス ( 4D v19.1)
ランゲージリファレンス ( 4D v19.4)
ランゲージリファレンス ( 4D v19.5)
ランゲージリファレンス ( 4D v19.6)
ランゲージリファレンス ( 4D v19.7)
ランゲージリファレンス ( 4D v19.8)