4D v17のオブジェクト、v15プロジェクトからの移行時の注意
オブジェクト型を使う際に気をつけたいことに遭遇したので記す。今回はv15以前からのプロジェクトをv17に変換したケース。
当社では「JCL4D」という共通ライブラリを用意していて、v15以降でサポートされたMETHOD xxコマンドを使って、プロジェクトに読み込んで利用している。JCL4Dは各メソッドをテキストファイルに書き出して、GitHubにて管理している。
最近このJCL4D v17版を作成した。以下「JCL4Dv17」にはフォームをリサイズする機能が含まれている。ユーザがウインドウをリサイズした際に、4Dの拡大/縮小的な動きではなく、ボタン、リストボックス、フィールドの縦横が拡大/縮小、フォントサイズも大きくなったり小さくなったりする、ズームのような機能だ。ユーザがリサイズした際のズーム比率や、フォーム上のオブジェクトの座標を覚えておいて、あとでセットするために、オブジェクト型の変数を構造体のように使って実装した。この機能をv15から変換したプロジェクトにも読み込もうとしたところ、今回のケースに遭遇。
データベース設定の互換性のところに次のオプションがある。v15から変換したプロジェクトでは、このチェックは外れている。
□ オブジェクト記法を使用してオブジェクトのプロパティにアクセスする
JCL4Dv17はこのチェックがついていることを前提にしているので、どの道チェックすることになる。チェックしてからメソッドをインポートすれば問題は起こらなかった。うっかりチェックを外した状態で、自社製インポートメソッドJCL_A_method_importを実行すると、オブジェクト参照のところに変なゴミが入る。外部テキストファイルからメソッドを読み込んでMETHOD SET CODEするメソッドだ。問題の箇所を一部抜粋したのが次のコード(A)。
このコードでは、親メソッドから第三引数にオブジェクトのポインタをもらって、そのフィールドを参照している。「$inObjPtr->rowsHeight」となっていたコードにドット(.)が挿入されて「$inObjPtr->.rowsHeight」になっている。もとの外部テキストファイルのコードは次(B)。
…
C_POINTER($3;$inObjPtr) //リストボックス情報オブジェクト
$inObjPtr:=$3
…
//行の高さ
C_LONGINT($rowsHeight)
$rowsHeight:=($inObjPtr->rowsHeight)*$ratio
LISTBOX SET ROWS HEIGHT(*;$inListbox;$rowsHeight)
…
データベース設定で「オブジェクト記法を使用してオブジェクトのプロパティにアクセスする」にチェックしてから、あらためて外部テキストファイルからメソッドを読み込んでMETHOD SET CODEしてみたのが次のコード(C)。
「$inObjPtr->」の後ろのプロパティ名が認識されて、カラーシンタックスが正しく適用されている。ドットは挿入されていない。
「$inObjPtr->」は実体であるため、実体にドットを付けてobject.propertyという形に勝手に変更されてしまったのだろうか。METHOD SET CODEの仕様なのか、別のコマンドによるものか確認はしていない。
いずれにしてもv17以降では、そもそもオブジェクト型の変数は、もともとポインタのようなものだから、引数に渡す際にポインタにする必要がない。C_TEXTやC_LONGINT型の変数と同じように、オブジェクト型のまま渡せば良くて、参照渡しなのでプロパティに値を代入して戻すこともできる。
だから上記のコードも次のように変更するべきだ。
【注意】この表記はv15以前ではサポートされていない。