Skip to main content

This is documentation for Caché & Ensemble. See the InterSystems IRIS version of this content.Opens in a new tab

For information on migrating to InterSystems IRISOpens in a new tab, see Why Migrate to InterSystems IRIS?

データ型を使用した作業

ObjectScript には、JSON の truefalse、および null に相当する個別の固定値は用意されておらず、JSON には値が定義されていない配列要素という概念はありません。この章では、これらの不一致点について説明して、これらの不一致点に対処するために Caché で用意されているツールを紹介します。

%GetTypeOf() を使用した値のデータ型の検出

%GetTypeOf() メソッドを使用して、ダイナミック・エンティティ・メンバのデータ型を取得できます。ダイナミック・オブジェクトのプロパティや配列要素のデータ型は、以下のいずれでもかまいません。

  • オブジェクトのデータ型 :

    • array — 動的配列の参照

    • object — ダイナミック・オブジェクトの参照

    • oref — ダイナミック・エンティティではない Caché オブジェクトの参照

  • リテラル値 :

    • number — キャノニック形式の数値

    • string文字列リテラル、または評価結果が文字列リテラルになる式

  • JSON リテラル :

    • boolean — JSON リテラルの true または false

    • null — JSON リテラルの null

  • データ型なし :

    • unassigned — そのプロパティまたは要素は存在しているが、値が割り当てられていない

オブジェクトでの %GetTypeOf の使用

このメソッドをオブジェクトに使用する場合、引数は、プロパティの名前になります。例えば、以下のようになります。

   set dynobj={"prop1":123,"prop2":[7,8,9],"prop3":{"a":1,"b":2}}
   set iter = dynobj.%GetIterator()
   while iter.%GetNext(.name) {write !,"Datatype of "_name_" is "_(dynobj.%GetTypeOf(name))}

Datatype of prop1 is number
Datatype of prop2 is array
Datatype of prop3 is object
配列での %GetTypeOf の使用

このメソッドを配列に使用する場合、引数は、要素のインデックスになります。次の例では、要素 2 に値が割り当てられていないスパース配列を調べます。この例では for ループを使用しています。%GetNext() は未割り当て要素をスキップするからです。

   set dynarray = [12,34]
   set dynarray."3" = "final"
   write dynarray.%ToJSON()
[12,34,null,null,"final"]

   for index = 0:1:3 {write !,"Datatype of "_index_" is "_(dynarray.%GetTypeOf(index))}
Datatype of 0 is number
Datatype of 1 is number
Datatype of 2 is unassigned
Datatype of 3 is string
array または object および oref の区別

ダイナミック・エンティティのデータ型は array または object になります。ダイナミック・エンティティではない Caché オブジェクトのデータ型は oref になります。次の例では、オブジェクト dyn の各プロパティはこれら 3 つのデータ型のいずれかです。プロパティ dynobject はクラス %DynamicObjectOpens in a new tab であり、プロパティ dynarray%DynamicArrayOpens in a new tab であり、プロパティ streamobj%Stream.GlobalCharacterOpens in a new tab です。

   set dyn={"dynobject":{"a":1,"b":2},"dynarray":[3,4],"streamobj":(##class(%Stream.GlobalCharacter).%New())}
   set iterator=dyn.%GetIterator()
   while iterator.%GetNext(.key,.val) { write !, "Datatype of "_key_" is: "_dyn.%GetTypeOf(key) }

Datatype of dynobject is: object
Datatype of dynarray is: array
Datatype of streamobj is: oref

%Set() または %Push() を使用したデフォルトデータ型のオーバーライド

既定では、システムは自動的に、%Set() または %Push() の値引数をオブジェクトのデータ型 (objectarray、または oref) または Caché リテラルのデータ型 (string または number) として解釈します。JSON リテラルの nulltrue、または false を値として直接渡すことはできません。この引数は Caché のリテラルまたは式として解釈されるからです。例えば、次のコードでは、Caché は true を変数名として解釈するため、エラーがスローされます。

   do o.%Set("prop3",true)

DO o.%Set("prop3",true)
^
<UNDEFINED> *true

Caché は、null の代わりに "" (空の文字列) を使用し、ブーリアン値 false の代わりに 0 を使用し、ブーリアン値 true の代わりにゼロ以外の数字を使用します。この問題に対処するために、%Set()%Push() は、対象の値のデータ型を指定するためのオプションの 3 つ目の引数を取ります。この 3 つ目の引数には、JSON の boolean または null を使用できます。以下に例を示します。

   write {}.%Set("a",(2-4)).%Set("b",0).%Set("c","").%ToJSON()
{"a":-2,"b":0,"c":""}

   write {}.%Set("a",(2-4),"boolean").%Set("b",0,"boolean").%Set("c","","null").%ToJSON()
{"a":true,"b":false,"c":null}

対象の値を数値として解釈可能な場合は、3 つ目の引数には string または number を使用することもできます。

   write [].%Push("023"_"04").%Push(5*5).%ToJSON()
["02304",25]

   write [].%Push(("023"_"04"),"number").%Push((5*5),"string").%ToJSON()
[2304,"25"]

JSON の NULL 値とブーリアン値の解決

JSON 構文では、truefalse、および null という値は、10、および "" (空の文字列) という値とは異なりますが、ObjectScript ではこのような区別はされません。JSON の値が要素またはプロパティから取得されると、それらの値は常に ObjectScript に対応した値にキャストされます。すなわち、JSON の true は常に 1 として返され、false0 として返され、null"" として返します。ほとんどの場合は、これは望ましい結果となります。その返り値は、最初に JSON フォーマットから変換することなく、Cache の式で使用できるからです。ダイナミック・エンティティの内部には JSON や Caché の元の値が保持されるため、%GetTypeOf() を使用して必要に応じて実際のデータ型を特定できます。

次の例では、動的配列コンストラクタによって、JSON の truefalse、および null の各値、数値と文字列のリテラル値、および ObjectScript のダイナミック式 (評価結果が Caché のブーリアン値 1 および 0 になるもの) が指定されます。

   set test = [true,1,(1=1),false,0,(1=2),"",null]
   write test.%ToJSON()
[true,1,1,false,0,0,"",null]

上記からわかるように、コンストラクタで割り当てられた値は、結果として得られる動的配列内に保持されていたため、JSON 文字列としてシリアル化されたときに適切に表示されます。

次の例では、配列の値を取得して表示します。予想どおり、JSON の値 truefalse、および null は Caché に対応した値 10、および "" にキャストされます。

   set iter = test.%GetIterator()
   while iter.%GetNext(.key,.val){write "/"_val_"/ "}
/1/ /1/ /1/ /0/ /0/ /0/ // //

この例では %GetNext() を使用していますが、%Get()%Pop()、またはドット構文を使用して値を取得した場合でも同じ結果が得られます。

必要に応じて、%GetTypeOf() メソッドを使用して値の元のデータ型を確認できます。以下に例を示します。

   set iter = test.%GetIterator()
   while iter.%GetNext(.key,.val) {write !,key_": /"_test.%Get(key)_"/ = "_test.%GetTypeOf(key)}
0: /1/ = boolean
1: /1/ = number
2: /1/ = number
3: /0/ = boolean
4: /0/ = number
5: /0/ = number
6: // = string
7: // = null
Note:
ダイナミック・オブジェクト内のデータ型

この章では動的配列を主に扱っていますが、同じデータ型変換がダイナミック・オブジェクトの値にも適用されます。このセクションの例は、動的配列 test がダイナミック・オブジェクトとして定義されている場合でもまったく同じように動作します。

   set test = {"0":true,"1":1,"2":(1=1),"3":false,"4":0,"5":(1=2),"6":"","7":null}

この行を除いて、サンプル・コードのどの部分も変更する必要はありません。このオブジェクト内のプロパティ名は、元の配列のインデックス番号に対応する数値文字列であるため、出力もまったく同じになります。

NULL、空の文字列、および未割り当て値の解決

JSON の null 値を要素やプロパティに割り当てることができますが、その値は常に "" (Caché の空の文字列) として返されます。未割り当て要素の値を取得しようとした場合にも、空の文字列が返されます。%GetTypeOf() を使用して、各ケースの実際のデータ型を特定できます。

この例では、JSON の null 値と空の文字列が含まれたスパース配列を調べます。配列要素 2 には値が割り当てられていませんが、この要素は JSON 文字列内では null で表現されます。

   set array = [null,""]
   do array.%Set(3,"last")
   write array.%ToJSON()
[null,"",null,"last"]

ほとんどの場合は、%GetNext() を使用して配列値を取得しますが、この例では、for ループを使用して、%GetNext() を使用した場合はスキップされる未割り当て値を返します。最終要素のインデックス番号は array.%Size()-1 ですが、ループ・カウンタは配列の末尾を越えて処理を続行するように意図的に設定されています。

   for i=0:1:(array.%Size()) {write !,i_". value="""_array.%Get(i)_""" type="_array.%GetTypeOf(i)}
0. value="" type=null
1. value="" type=string
2. value="" type=unassigned
3. value="last" type=string
4. value="" type=unassigned

この例では、%Get() は以下の 4 つのケースで空の文字列を返します。

  1. 要素 0 は JSON の null 値であり、%GetTypeOf() によってデータ型 null として識別されます。

  2. 要素 1 は空の文字列であり、データ型 string として識別されます。

  3. 要素 2 は値を持っていないため、データ型 unassigned として識別されます。

  4. 要素 3 が最後の配列要素ですが、この例では、存在しない要素 4 のデータ型を取得しようとします。この要素もデータ型 unassigned として識別されます。有効な配列インデックス番号は常に array.%Size() より小さい値になります。

Note:

nullunassigned の区別は、ダイナミック・エンティティが JSON 文字列にシリアル化されたときに保持されない Caché メタデータです。すべての unassigned 要素は null 値としてシリアル化されます。詳細は、“スパース配列と未割り当て値の理解” を参照してください。

FeedbackOpens in a new tab