Jsonオブジェクトで配列の型を取得したい。

4D : v15.4

OB Get typeでプロパティの型を取得できますが、プロパティが配列の場合は型がすべてオブジェクト配列に
なってしまいます。
配列の型を取得する方法は無いでしょうか?

はい。

OB SET ARRAYでオブジェクトにセットした配列は,
配列としての「型」は失っていますので,
申し訳ないのですが,型を取得する,という方法で扱うことはできません。
(逆に,セットしたのとは違う型で取り出すことはできます)

そうかぁ、JSONの配列は要素ごとに型が違っていていいんですよねぇ。
v16で導入されたコレクションがJSONの配列ですよね。
だとすると要素ごとの型は失われていないと思うのですが、要素ごとの型を取得することは
できないのでしょうか?

今テストしていたのですが、object配列をtext配列で受けると、"[Object object]”という文字列が
返ってくるのですが、これは決定された仕様でしょうか?

コレクションについて

16R4のコレクション型(C_COLLECTION)は,
要素ごとに型が違ってもよい,という意味で,
型が決まっていない(揃っていない)配列のようなものです。

コレクション型は,
オブジェクト型と同じように,
原則的にNewコマンドで作ります。

$col:=New collection(123;“miyako”)

または

$c:=JSON Parse("[123,“miyako”]")

JSON Parseは文字列がオブジェクトではあればオブジェクト,
配列であればコレクションを返します。

オブジェクト型と同じように,
コレクション自体に値がセットされるわけではなく,
値に対する「参照」がセットされます。

ですから,
$collection_1:= $collection_2
はコピーを作ることにはなりません。

ただし,
New processの引数に渡された場合には,
暗黙的にコピーが作られます。

別プロセスに対するCALL WORKER・CALL FORMも同様です。

〜ここからが重要〜

OB Get type およびOB GET PROPERTY NAMESは,
プロパティがコレクションであれば42 (is collection)を返します。
従来は39 (Object array)でした。

(コレクションではない)配列は,
たまたま値の型が揃っているコレクションとみなすことができますから,
タイプは42 (is collection)あるいは39 (Object array)であり,
Longint array,Text arrayといった型ではありません。

そういう意味で,型の情報が失われている,と申し上げました。

要素毎に型が違っている配列(JSON配列)については,
16R3以前の4D言語には相当するものがありませんので,
コレクション型をご検討ください。

コレクション型は,
OB SET ARRAY・OB GET ARRAYが内部的に使用していた仕組みを公開したものです。
日付は文字列,時間はミリ秒(実数),整数も実数に変換されており,
元のスカラー型や日付構造体ではなくなっています。

フォームオブジェクトとしては,
標準テキスト入力(オブジェクトと同じ)
あるいはサブフォーム(ウィジェット)のバインド変数として使用できます。

一方,フィールドは非サポートであり,
コレクションの「配列」というものもありません。
演算子・プラグイン・PHP・SQL・ピクチャのメタデータも非サポートです。
リストボックスの列にもなりません。

制限が多いように感じると思いますが,
コンパイルできる「型」として提供するための措置となっています。

HTTP GetおよびHTTP Request(入出力)はサポートしており,
通常の変数と同じ感覚で,

VARIABLE TO VARIABLE
VARIABLE TO BLOB
BLOB TO VARIABLE
SET PROCESS VARIABLE
GET PROCESS VARIABLE
SEND VARIABLE
RECEIVE VARIABLE

に渡すことができます。

引数としてコレクション型をサポートするコマンド(TypeとOB系は割愛)は以下のとおりです。

PROCESS 4D TAGS
New process
CALL WORKER
CALL FORM
EXECUTE METHOD
EXECUTE METHOD IN SUBFORM
Execute on server
EXECUTE ON CLIENT
WA Evaluate JavaScript
WA EXECUTE JAVASCRIPT FUNCTION

これにメソッドおよび「サーバー上で実行」メソッドが加わります(戻り値も)。

配列全体の型が意味がないのはわかりましたが、配列あるいはコレクションの各要素ごとの型を
取得することはできないのでしょうか?

通常どおりTypeで調べることができます。

例:

C_COLLECTION($col)

$col:=New collection(Random;Current date;Current user)

For ($i;0;$col.length)

ALERT(String(Type($col[$i])))

End for

ありがとうございます。

無事、型を取得できました。
OB SET ARRAYで追加した配列は自動的(?)にコレクションになるんですね。
要素に違う型をいれても問題なく動作しました。

ところでデータベース設定でオブジェクト記法を有効化させると、コンパイルできなくなるという警告文が
表示されますが、試しにコンパイルするとコンパイル&実行できます。

コンパイル可能と考えて良いのでしょうか?

[]19656112;“Your comment here…”[/]

はい。

ドット記法はコンパイルできる仕様となっています。

ただ,Rバージョンのベータ期間中は,コンパイラの改定が間に合わず,
数日間,コンパイルができないビルドがリリースされる可能性があったので,
あのような表記となりました。

ただ,今のところ,コンパイルができないビルドはリリースされていないようです。

それからもう1件,ドット記法を有効にした後は,16R3以前で再コンパイルができなくなります。(ランタイムバージョンが違うため)

通常,Rで開いた4DBは同じバージョン番号であれば,下位のRあるいは非Rで開くことができます。

上位R限定コマンドを追加した場合,そのコマンドは下位バージョンで消えますが,それでもメソッドがコンパイルできなくなることはありませんでした。

なるほど

少しいじってみましたが、このオブジェクト記法は素晴らしいですね!

速度的な検証が必要ですが、キーバリューデータベースのシステムも構築できそうです。
昔Casheのようなデータベースを探してたこともあり、その事例に応用できるのではとワクワクしてます。

Rリリースでの製品版はちょっと怖いので、早期のv17リリースを期待してます!