Main Content

変更済みクラスの自動更新

MATLAB がクラス定義を読み込む場合

MATLAB® は、以下の場合にクラス定義を読み込みます。

  • インスタンスの作成、定数プロパティへのアクセス、クラスの静的メソッドの呼び出しなど、クラスが最初に参照されたとき。

  • 読み込まれたクラスの定義が変更され、MATLAB がコマンド プロンプトに戻ったとき。

  • MATLAB パスを変更したために、使用するクラスの定義が変わってしまったとき。変更は、MATLAB がコマンド プロンプトに戻った後に有効になる。

  • クラスのメタデータにアクセスするときに常時。

MATLAB では、1 つのクラスにつき一度に 1 つの定義しか使用できません。このため、MATLAB は、そのクラスのすべての既存オブジェクトが新しいクラス定義に自動的に準拠するよう更新を試みます。既存のオブジェクトの定義クラスを変更するとき、clear classes を呼び出してそれらのオブジェクトを削除する必要はありません。

メモ

MATLAB エディター以外のエディターまたは MATLAB Online™ を使用すると、自動更新が遅れる可能性があります。

自動更新の結果

MATLAB は、既存のオブジェクトを更新するとき基本的な一連のルールに従います。自動更新により生じる結果には以下があります。

  • 既存のオブジェクトが新しいクラス定義に更新されます。

  • MATLAB がオブジェクトを新しいクラス定義に変換できないか、クラス定義自体にエラーがある場合、エラーになります。

次の例は、具象クラスのインスタンスを作成した後、そのクラスの定義を編集して抽象クラスにすると何が起こるかを示しています。

a = MyClass;
% Edit MyClass to make it Abstract

a
Error using MyClass/display
Cannot update object because the class 'MyClass' is now abstract.

メモ

MATLAB は、クラス定義が変更されてもメタクラス インスタンスを更新しません。クラス定義の更新後に新しいメタクラス データを取得しなければなりません。

クラス定義が変更された場合

MATLAB は、以下の状況を含むクラス定義の変更時に、既存オブジェクトの更新を行います。

  • ハンドルする値の変更 — 既存のオブジェクトは、異なるオブジェクトを参照する独立ハンドルになります。

  • 列挙メンバーの追加 — 既存のオブジェクトは、列挙メンバーの基となる値が変化しても、以前の列挙メンバーを保持します。

  • 列挙メンバーの削除 — 削除されたメンバーを使用しない既存のオブジェクトは、以前と同じ列挙メンバーをもちます。削除されたメンバーを使用する既存のオブジェクトは、削除されたメンバーを列挙型の既定のメンバーで置き換えます。

  • 列挙型ブロックの削除 — 列挙メンバーは使用されなくなります。

  • スーパークラス定義の変更 — 変更はそのスーパークラスの階層内のすべてのサブクラスに適用されます。

  • スーパークラスの追加または削除 — スーパークラスの変更がすべての既存のオブジェクトに適用されます。

定義フォルダーをスコープ内に確実に保持

MATLAB パスを変更することにより、そのパスからクラス定義ファイルが削除されると、一時的にでも副次的な影響が発生することがあります。関数がクラス定義を含む現在のフォルダーから変更され、そのフォルダーがパス上にない場合、その関数はスコープ外となったクラスのメソッドを呼び出すことができなくなります。潜在的な問題を回避するには、他のフォルダーに変更する前に、クラス定義フォルダーをパスに追加します。

たとえば、入力 obj のクラスが現在のフォルダーに定義され、そのフォルダーがパス上にないとします。現在のフォルダーを他のフォルダーに変更する前に、関数 addpath を使用して現在のフォルダーをパスに追加します。

function runFromTempFolder(obj)
    % Add current folder to path
    addpath(pwd)
    definingFolder = cd('myTempFolder');
    obj.myMethod;
    cd(definingFolder)
end

更新を引き起こさない操作

以下の操作は既存のオブジェクトを更新しません。

  • 古くなったオブジェクトへの関数 class の呼び出し

  • 古くなったオブジェクトの変数への代入

  • クラス データにアクセスしないメソッドの呼び出し

  • クラス定義でのプロパティ検証の変更 (プロパティ値の検証)

オブジェクトは、オブジェクト表示の呼び出しやプロパティへの割り当てなど、変更が明らかになる方法で参照されない限り更新されません。

クラス定義の複数の更新

更新はインクリメント形式では行われません。更新はクラスの最新バージョンに準拠します。

クラス ファイルの削除によるオブジェクトの有効性

クラス定義ファイルを削除しても、そのクラスのインスタンスは無効になりません。ただし、そのクラスの既存のオブジェクトでメソッドを呼び出すことはできません。

更新が不可能な場合

クラスの更新によりクラス定義が無効になることがあります。そのような場合、エラーが解決されるまでオブジェクトは更新されません。

  • スーパークラスを追加すると、プロパティまたはメソッドが 2 度定義されることがあります。

  • サブクラスの 1 つにオブジェクトが存在する場合にそのスーパークラスを Sealed に変更すると、サブクラス定義が無効になることがあります。

クラスの更新によっては、MATLAB が既存のオブジェクトを、変更されたクラス定義に準拠するように更新できない、という状況が発生します。次のような場合、オブジェクトを削除するまでエラーの原因となります。

  • enumeration ブロックを非列挙クラスに追加

  • クラスを抽象クラスとして再定義

  • 異種混合階層からクラスを削除 (その結果、異種混合配列内の既存のオブジェクトに置き換わる既定のオブジェクトが存在しない)

  • 配列インデックス付けのオーバーロードや連結など、配列の形成動作を制限するためにクラスを更新

  • subsrefsubsasgncatvertcat または horzcat メソッドを継承

  • ハンドル クラスを値クラスとして再定義

クラスの更新により起こりうる結果

  • 更新の後、既存のオブジェクトが新しいクラス定義と互換性がなくなる場合があります。たとえば、新たに追加されたプロパティを有効にするには、コンストラクターの実行が必要な場合があります。

  • プロパティを削除したり名前を変更すると、そのプロパティのもつデータが失われる場合があります。たとえば、他のオブジェクトへの唯一の参照があるプロパティをクラスから削除すると、そのオブジェクトへの参照がなくなるので MATLAB はそのオブジェクトを削除します。

  • 異種混合クラス階層からクラスを削除すると、異種混合配列要素が無効になる場合があります。この場合、それらの配列要素はその異種混合階層の既定のオブジェクトで置き換えられます。

デバッガーの操作

R2021a 以降

MATLAB は、クラスの更新中にデバッガーを無効にします。R2021a より前は、ブレークポイントによってクラス更新プロセスが中断される可能性があり、更新の再開時に誤差が生じることがあります。たとえば、ブレークポイントを使用すると、クラス作成者がクラス定義に無効な構文を導入したり、クラスをパスから完全に削除したりして、MATLAB がクラッシュする可能性があります。

無効化されたブレークポイントの例

次のクラスはプロパティ検証関数を定義します。

classdef ClassWithBreakpoint
    properties (Constant)
        Prop1 (1,1) {myPropertyValidator} = 32
    end
end

function myPropertyValidator(~)
end % Add breakpoint here
このクラスのインスタンスを作成します。次に、指示がある場所にブレークポイントを追加し、Prop1 の定義を異なる初期値に更新します。
Prop1 (1,1) {myPropertyValidator} = 10
R2020b 以前のバージョンでは、MATLAB がブレークポイントにヒットすると、クラスの更新が中断されます。R2021a では、デバッガーは無効になっているため、ブレークポイントによって更新が中断されることはありません。

クラス属性の更新

クラス属性の変更により、既存オブジェクトの動作が変化したり、オブジェクトが無効になったりする場合があります。無効なオブジェクトにアクセスすると、MATLAB はエラーを返します。

変更結果

Abstract = true に設定

既存オブジェクトにアクセスすると、エラーが返されます。

AllowedSubclasses を変更

新しく作成されるオブジェクトが既存オブジェクトからではなく、別のスーパークラスから継承される場合があります。

ConstructOnLoad を変更

クラスの読み込みは ConstructOnLoad の現在の値に従います。

HandleCompatible を変更

新しく作成されるオブジェクトが既存オブジェクトとは異なるクラス階層をもつ場合があります。

Hidden を変更

スーパークラスのリスト内でのクラスの外観と関数 help によるアクセスが変更される場合があります。

InferiorClasses を変更

既存オブジェクトのメソッド ディスパッチングが変更される場合があります。

Sealed = true に設定

既存のサブクラス オブジェクトにアクセスするとエラーが返されます。

プロパティ定義の更新

クラス プロパティの定義を変更すると、MATLAB はその変更をクラス内の既存のオブジェクトに適用します。

変更結果

プロパティの追加

クラスの既存のオブジェクトに新しいプロパティが追加されます。プロパティ値が既定値に設定されます (クラス定義に既定値が指定されていない場合は [])。

プロパティの削除

クラスの既定のオブジェクトからプロパティが削除されます。削除されたプロパティにアクセスする試みが失敗します。

プロパティの既定値の変更

クラスの既存のオブジェクトには新しい既定値は適用されません。

サブクラスとスーパークラス間でのプロパティの移動

プロパティの定義がスーパークラスとサブクラスの間で動かされても、異なる既定値は適用されません。

プロパティの属性値の変更

クラスの既存のオブジェクトに変更が適用されます。

以下の中間手順が必要な場合があります。

  • Abstract — クラスが抽象になる既存のオブジェクトは更新できません。これらのオブジェクトは削除してください。

  • Accesspublicprotected または private プロパティのアクセス設定への変更は、既存オブジェクトへのアクセスに影響します。

    アクセス リストへの変更は既存のオブジェクトに影響しません。ただし、クラスをアクセス リストに追加すると、それらのクラスのインスタンスはこのプロパティにアクセスできるようになります。クラスをアクセス リストから削除すると、それらのクラスのオブジェクトはこのプロパティにアクセスできなくなります。

  • Dependenttrue に変更すると、既存のオブジェクトはプロパティ値を保存しなくなります。プロパティ値をクエリするには、そのプロパティの get メソッドを追加します。

  • Transienttrue に変更すると、既に保存されているオブジェクトはこのプロパティ値を再読み込みします。false に変更すると、既に保存されているオブジェクトは既定値を使ってこのプロパティを再読み込みします。

メソッド定義の更新

クラス メソッドの定義を変更すると、MATLAB は既存のオブジェクト内で影響を受けるクラス メンバーを次のように変更します。

変更結果

メソッドの追加

このクラスの既存のオブジェクトで新しいメソッドが呼び出せます。

メソッドの変更

変更内容が既存のオブジェクトで利用可能になります。

メソッドの削除

削除されたメソッドを既存のオブジェクトで呼び出せなくなります。

メソッド属性値の変更

クラスの既存のオブジェクトに変更が適用されます。

以下の中間手順が必要な場合があります。

  • Abstract — クラスが抽象になる既存のオブジェクトは更新できません。これらのオブジェクトは削除してください。

  • Access — メソッド publicprotected または private のアクセス設定への変更は、既存オブジェクトへのアクセスに影響します。

    アクセス リストへの変更は既存のインスタンスに影響しません。ただし、クラスをアクセス リストに追加すると、それらのクラスのインスタンスはこのメソッドにアクセスできるようになります。クラスをアクセス リストから削除すると、それらのクラスのオブジェクトはこのメソッドにアクセスできなくなります。

  • Sealedtrue に変更され、既存のサブクラスによってメソッドが既に定義されている場合、新しいクラス定義を既存のサブクラスに適用できないため MATLAB はエラーを返します。

イベント定義の更新

変更結果

イベントの追加

クラスの既存オブジェクトは新しいイベントをサポートします。

イベント名の変更

新しいイベント名はクラスの既存のオブジェクトに認識されます。MATLAB は、

  • 既存のメタクラス オブジェクトを更新しない

  • 新たに取得されたメタクラス オブジェクトを更新する

  • 新しいイベント名を使用するためのリスナー更新は行わない

イベントの削除

既存のオブジェクトは削除されたイベントをサポートしなくなります。

イベント属性値の変更

クラスの既存のオブジェクトに変更が適用されます。

以下の中間手順が必要な場合があります。

  • ListenAccess — イベント publicprotected または private の listen アクセス設定への変更は既存のオブジェクトへのアクセスに影響します。

    アクセス リストへの変更は既存のオブジェクトには影響しません。ただし、アクセス リストにクラスを追加すると、これらのクラスのオブジェクトはこのイベントのリスナーを作成できます。アクセス リストからクラスを削除すると、これらのクラスのオブジェクトはこのイベントのリスナーを作成できません。

  • NotifyAccesspublicprotected または private の notify アクセス設定への変更は既存オブジェクトに影響します。

    アクセス リストへの変更は既存のオブジェクトには影響しません。アクセス リストにクラスを追加すると、これらのクラスのインスタンスはこのイベントをトリガーできます。クラスを削除すると、これらのクラスのオブジェクトはこのイベントをトリガーできません。

関連するトピック