標準コマンドは,スレッドセーフ(プリエンプティブモードで実行できる)あるいはアンセーフ(できない)のどちらかなので,スレッドセーフではないコマンドをプリエンプティブプロセスから呼び出そうとしているようなメソッドは,コンパイル時にエラーが返されます。ただし,Get database parameter
とSET DATABASE PARAMETER
は例外です。これらのコマンドはスレッドセーフですが,実際にプリエンプティブプロセスから呼び出せるかどうかはセレクター値に左右されます。スレッドセーフなセレクターは以下のとおりです。挙げられていないセレクターをプリエンプティブプロセスで指定した場合,ランタイムエラー「スレッドセーフではないコマンドをプリエンプティブプロセスから呼び出せません。」が返されます。
値 | 定数 | get | set |
---|---|---|---|
28 | 4D Server log recording | ✅ | ✅ |
34 | Debug log recording | ✅ | ✅ |
65 | (undocumented) | ✅ | ✅ |
79 | Diagnostic log recording | ✅ | ✅ |
80 | Log command list | ✅ | |
86 | Diagnostic log level | ✅ | ✅ |
90 | Circular log limitation | ✅ | ✅ |
95 | Cache flush periodicity | ✅ | ✅ |
108 | User param value | ✅ | |
110 | SMTP Log | ✅ | ✅ |
111 | Current process debug log recording | ✅ | ✅ |
112 | Is current database a project | ✅ | ✅ |
113 | Is host database a project | ✅ | ✅ |
116 | POP3 Log | ✅ | ✅ |
119 | IMAP Log | ✅ | ✅ |
121 | Pause logging | ✅ | ✅ |
オブジェクト型は,メモリに存在するオブジェクトに対する参照です。オブジェクト型を変数に代入したり,パラメーターとしてメソッドや関数に渡した場合,オブジェクトのコピーが作成される代わりにオブジェクトの参照カウントがインクリメントされます。オブジェクトを参照している変数に別のオブジェクトが代入された場合,あるいは変数やパラメーターがクリアされた場合,オブジェクトが消去される代わりにオブジェクトの参照カウントがデクリメントされます。参照カウントがゼロに達すると,オブジェクトが占有していたメモリが解放されます。
オブジェクト型またはコレクション型をオブジェクト型のプロパティまたはコレクション型のメンバーに代入した場合,代入しようとしているオブジェクト型またはコレクション型が代入されようとしているオブジェクト型またはコレクション型から直接的あるいは間接的に参照されているかどうかをチェックする必要があります。つまり,再帰的な参照の有無を調べる必要があります。再帰的な参照をきちんと管理しないと,正しいタイミングで参照カウントがゼロにならないためです。
代入の対象となっているオブジェクト型の一部分(たとえば上位のプロパティ)をすでに参照しているようなオブジェクト型またはコレクション型をオブジェクト型のプロパティまたはコレクション型のメンバーに代入した場合,参照の数に応じて代入に要する時間が長くなります。
$oMap:={}
For ($i; 1; $iterations)
$o:={col: []; o: {}}
$o.map:=$oMap
$oMap[String($i)]:=$o
End for
この例では,親オブジェクト$oMap
に対する参照がすべての子オブジェクトが持つ.map
プロパティに代入されているので,子オブジェクトを追加するたびに親オブジェクトの参照が増えてゆき,代入のスピードがどんどん遅くなってゆきます。それぞれの子オブジェクトは,{col: []; o: {}}
,つまり,1
個のオブジェクトと1
個のコレクションからなるシンプルなオブジェクト型としてインスタンス化されますが,.map
プロパティに親オブジェクト$oMap
を代入するためには,まず,代入しようとしている親オブジェクト$oMap
が代入されようとしている子オブジェクト$o
から参照されているかどうかをチェックする必要があるためです。回数を重ねるごとに親オブジェクトが持つ参照の数は増えてゆき,直接的な参照だけでなく,間接的な参照もすべてチェックしなければならないので,このチェックに要する時間はどんどん長くなります。もっとも,$o
はインスタンス化されたばかりのオブジェクトであり,すべての参照をチェックしたところで$oMap
からの参照はありません。相互に対する参照が生まれるのは,親オブジェクトを子オブジェクトを代入した後のことです。
つづく代入文でも,代入しようとしている子オブジェクト$o
が代入されようとしている親オブジェクト$oMap
から参照されているかどうかをチェックする必要がありますが,このときのチェックは瞬時に終わります。$o
の.map
プロパティが親オブジェクトを参照しているので,これは再帰的なオブジェクトです。
このことを理解すると,代入の順序を入れ替えるだけで,実行の速度が劇的に向上することに気づきます。
$oMap:={}
For ($i; 1; $iterations)
$o:={col: []; o: {}}
$oMap[String($i)]:=$o
$o.map:=$oMap
End for
子オブジェクト$o
を発展させる前に,まず,親オブジェクトに代入して,再帰的な参照を確立させているのがポイントです。この時点で$o
には,メンバーである1
個の空オブジェクトと1
個の空コレクション,そしてオブジェクトそのものを加えた合計3
個の参照しかありません。そして再帰的な参照もありません。なのでチェックはすぐに終わります。つぎに子オブジェクトの.map
プロパティに親オブジェクト$oMap
を代入しますが,この時点で両オブジェクトはすでに互いを参照しているので,やはりチェックは瞬時に終わります。
つまり,再帰的な参照を持つオブジェクト型またはコレクション型を代入文で構築する場合,まず部品を完成させてから本体に連結するのではなく,さきに参照だけ連結させてから個別の部品を「肉付け」したほうが良い,ということになります。オブジェクトの参照が少ないうちに再帰的な代入をしたほうが,オブジェクトの参照が多くなってから代入するよりも効率的だからです。
20 R7以降のフィーチャーリリース(開発中のバージョン)では,Windows版のリソースフォルダーに.pri という拡張子を持つファイルがあることに気づくかもしれません。PRI (Package Resource Indexing)ファイルは,WindowsApp SDKが自動的に生成するものであり,WinUIのリソースが収録されています(リリース版では取り除かれるかもしれません)。
WinUIモードは,Windows版でよりネイティブなルック&フィールを実現するために開発が進められている新しいユーザーインタフェースです(膨大な計画であり,完成まで数年を要することが予想されています)。
デバッガのウォッチエリアには「式を挿入」することができます。20 R7以降のフィーチャーリリースではリクエストに応え,保存ボタンをクリックしなくても,自動的に設定が保存されるようになります。
デバッガ/リモートデバッガの設定は,カレントユーザー毎(userPreferences.{user})に管理されています。
拡張された仕様では,メソッド/関数毎に式がセーブ/ロードされるようになります。つまり,別のコンテキストで開いたデバッガのウォッチエリアには表示されません。デバッガを開いたメソッド/関数に関係なく,特定の式をウォッチエリアに追加したい場合,Xcode/Visual Studioなどの代表的なIDEに準拠し,その式をデバッガのウォッチエリアに「ピン」留めします。
プロジェクトモードでは,フォームオブジェクトのプロパティをCSSファイルで管理することができます。CSSは,HTMLを修飾するための言語として有名ですが,4Dの場合,フォームオブジェクトの属性つまりプロパティ全般をCSSで設定します。
たとえば,下記の要領でボタン・テキスト・入力オブジェクトのフォント名をまとめて設定することができます。
button,text,input {
font-family: Helvetica Neue;
font-size: 20px;
}
CSSのルールによれば,オブジェクトタイプ(HTMLの要素セレクターに相当)よりもオブジェクト名(HTMLのIDセレクターに相当)のほうがスペシフィシティ(詳細度)が高いので,プロパティリストに値が入力されていると,CSSはオーバーライドされ,レンダリングに反映されません。プロパティリストに入力された値はcontrol キーを押しながら項目名をクリックすることでクリアできます。
フォント名はfont-family
で指定しますが,システムフォントは自動スタイル経由で,つまりfont-theme
でnormal を指定することにより,間接的に指定します。
button,text,input {
font-theme: normal;
}
つまり「システムフォント」「system font」などの”フォント名”をfont-family
に指定するのは間違いです。ただし,CSSやプロパティリスト(.4DForm ファイル)でフォント名が特に指定されていなければ,結果的にシステムフォントが採用されます(ACI0104997の注記を参照)。
4D Web Serverの予約されたURL(いわゆるマジックURL)のうち,4DCGI
は特別な意味を持たず,実質的に無効となっています。
2003以前のバージョンでは,4DCGI
で始まるURLをリクエストすることにより,On Web Authentication およびOn Web Connection データベースメソッドを実行させることができました。2004以降,何であれ「未知のURL」つまりWebフォルダー内のリソースにマッチしないURLは,On Web Authentication およびOn Web Connection データベースメソッドを実行するので,4DCGI
で始まるURLに特別な意味はありません。4DCGI
の仕組みは,ハッキング防止のために残されていますが,実際には「未知のURL」と同じ動作になります。