3

Progress10.1cを使用しています

静的メソッドと非静的メソッドの両方を含むクラスがあります。

クラスはUSE-WIDGET-POOLで定義されます。デストラクタでは、「DELETEWIDGET-POOL」と言います。

クラスのインスタンスを作成し、メソッドを呼び出します。メソッド自体は、クラスの静的メソッドの1つを使用します。したがって、正しく理解すれば、クラスのインスタンスが独自の名前のないプールにあり、クラスの静的メンバー用に別の名前のないウィジェットプールがあります。

ここまでは順調ですね。しかし、私はデバッグで忙しく、コードに変更を加えています。再コンパイルしてテストを再実行します。これで非静的メンバーは機能しますが、すべての静的メンバーは古いバージョンのクラスからのものであり、セッションにスコープされている静的メンバーのプールに引き続き保存されます。つまり、デストラクタの「DELETE WIDGET-POOL」は、クラスのインスタンスのプールを削除しましたが、静的メンバーのプールはまだ存在しています。

新しいバージョンのクラスをロードするための唯一の方法は、セッションからログオフしてから再度ログオンすることです。これは私たちの環境におけるかなりの使命です。変更を加えるたびに、開発環境を停止して開始する必要があります。

セッションでオブジェクトのリストを調べようとしましたが、探しているものが見つかりませんでした。間違ったオブジェクトから始めているか、進行中のプールとオブジェクトに関する知識が不足している可能性があります。

毎回セッションを破棄せずに、その名前のないプールをターゲットにして、クラスの静的な「インスタンス」を削除する方法はありますか?

4

3 に答える 3

2

これは、ごくわずかなコーディングで実行可能であることが判明しました。ステートメントDELETEOBJECTTHIS-OBJECTを使用して、そのステートメントを実行しているインスタンスを削除できます。したがって、静的メソッド内にある場合、削除されるのは静的インスタンスです。

METHOD STATIC VOID Reload () :
    DELETE OBJECT THIS-OBJECT.
END METHOD.

したがって、新しいバージョンのクラスがある場合は、MyClass:Reload()を使用するだけです。セッションを終了する必要はありません。

名前付きウィジェットプールを削除するために静的メソッドを使用するという彼の提案で私を正しい方向に向けてくれたTimKuehnに感謝します。


この例は、どのように機能させるかを示すために作成しました。以下は、3つの静的メソッドを持つ単純なクラスです。

/* File : rtt/cls/demo.cls */

USING Progress.Lang.*.
ROUTINE-LEVEL ON ERROR UNDO, THROW.

CLASS rtt.cls.demo USE-WIDGET-POOL :

    METHOD STATIC CHARACTER SayHello() :
      RETURN "Good-bye".
    END METHOD.

    METHOD STATIC VOID ShowMessage() :
      MESSAGE "This is the message." VIEW-AS ALERT-BOX.
    END METHOD.

    METHOD STATIC VOID Reload() :
      DELETE OBJECT this-object.
    END METHOD.

END CLASS.

他の人の環境がどのように設定されているかはわかりませんが、私の環境では、プログラムをコンパイルして実行できるようにシステムにログオンする必要があります。つまり、アクティブなセッションがあります。

だから私はファイルをコンパイルします:

COMPILE VALUE(SEARCH("rtt/cls/demo.cls")) SAVE.

次に、プロシージャエディタで次のビットを実行してテストします。

USING rtt.cls.*.

demo:ShowMessage().
MESSAGE demo:SayHello().

これを実行すると、「これはメッセージです。」というメッセージボックスが表示され、続いて「さようなら」というメッセージボックスが表示されます。まさに期待通りです。

しかし、バグがあり、「Good-Bye」ではなく「Hello」と表示されるはずなので、クラスを編集します(変更する2つのメソッドのみを表示しています。

    METHOD STATIC CHARACTER SayHello() :
      RETURN "Hello".
    END METHOD.

    METHOD STATIC VOID ShowMessage() :
      MESSAGE "That was the message." VIEW-AS ALERT-BOX.
    END METHOD.

変更を保存し、以前と同じようにコンパイルして、テストを再実行します。どのようなメッセージが表示されると思いますか?「これがメッセージです」と期待しています。と「さようなら」、前と同じ。これは論理的です。現在のセッションに非表示のウィジェットプールがあり、(最初のテストから)クラスのインスタンスがロードされているためです。インスタンスまたはプールが破棄されるまで、このインスタンスを使用し続けます。そこで、開発環境をシャットダウンし、ログオフしてから再度ログオンして、新しいセッションを開始します。これまでのところ、すべてが期待どおりに機能しています。

今度はテストを再度実行します。確かに、新しいバージョンを取得します。メッセージは「Thatwasthemessage」と「Hello」です。

しかし今、私は「こんにちは」という言葉の後に感嘆符を追加するように言われています。だから私はそれを変更します:

    METHOD STATIC CHARACTER SayHello() :
      RETURN "Hello!".
    END METHOD.

保存してコンパイルします。テストを実行すると、明らかに、感嘆符なしで「こんにちは」と表示されている古いバージョンが表示されます。変更がアクティブになる前に、セッションを再開する必要があります。私は本当にそれを二度とやりたくない。だから私は次のように私のテストを変更します:

USING rtt.cls.*.

demo:Reload().

demo:ShowMessage().
MESSAGE demo:SayHello().

私はそれを実行し、ボイラー、最新の変更を取得します。メッセージを「それがメッセージでした」から「動作します!」に変更します。テストを保存、コンパイル、実行します。何が見えますか?「うまくいく!」と表示されます。編集の合間にセッションを再開する必要はもうありません。私の解決策は私にとって完璧に機能します。

いろいろ試してみましたが、「静的メンバー(15071)からTHIS-OBJECTまたはSUPERを参照できません」というエラーが表示されません。

于 2012-06-20T08:51:14.710 に答える
1

静的クラス要素はABLセッションの間持続し、それらを「アンロード」する唯一の方法は、データベース接続をダウンさせることです(つまり、dbサーバーをシャットダウンします)。これにより、すべてがアンロードされ、クライアントコードがクリアされ、4GLエディターのままになります。

それを超えて、他の唯一の可能な方法は、静的クラスの名前付きウィジェットプールを作成し、(静的)メソッドを呼び出してそれを削除することです。これがうまくいくかどうかはわかりません。

于 2012-06-18T13:15:55.163 に答える
0

「クラスタイプにスコープされた静的メンバー。この名前のないウィジェットプールは、ウィジェットプールが作成されたABLセッションが終了した場合にのみ暗黙的に削除されます。」

http://documentation.progress.com/output/OpenEdge102b/pdfs/dvoop/dvoop.pdf5-9 ページ

この場合、何か問題が発生します。静的メンバーは、メソッドまたはプロパティにのみ使用する必要があります。これらは実際には静的であり、クラスのインスタンスが削除されたときに削除または再初期化してはなりません。

とにかくそれを使用するときは、名前を使用して独自の静的ウィジェットプールを定義し、このウィジェットプールで作成する静的動的オブジェクトを定義する必要があります。次に、Reload()で次のように記述できますか。

METHOD STATIC VOID Reload () :
  DELETE WIDGET-POOL XYZ.
  CREATE WIDGET-POOL XYZ.
END METHOD.

もう1つの方法は、この「静的」オブジェクトが定義されているsingeltonクラスを使用することです。その後、いつでも、いつでも、このシングルトンのインスタンスを削除して、新しいものを作成できます。

于 2012-06-20T11:50:26.303 に答える