R2019b での関数の優先順位の変更に対するコードの更新
R2019b 以降、MATLAB では名前の解決に関する規則が変更されており、変数、入れ子関数、ローカル関数、および外部関数の優先順位が影響を受けます。新しい規則により、名前の解決が単純化され標準化されます。詳細については、関数の優先順位を参照してください。
これらの変更により、関数 import
の動作が影響を受けます。コードを解析し、場合によっては更新する必要があります。最初に、コードの import ステートメントを検索します。たとえば、ファイルやフォルダーの検索を使用して、テキスト import
を含む .m
ファイルと .mlx
ファイルを検索します。以下の変更による影響を評価する際には、これらの検索結果を参照してください。
1 つの関数内で識別子を 2 つの目的に使用することはできない
R2019b 以降、識別子をまずローカル関数またはインポートされた関数として使用し、次に変数として使用すると、エラーが発生します。以前のリリースでは、識別子は関数のスコープ内で異なる目的に使用可能であり、その結果あいまいなコードにつながりました。
この動作変更がコードに影響する場合は、変数か関数の名前を変更して、これらが異なる名前をもつようにします。
R2019b 以降 | 更新されたコード | R2019a 以前 |
---|---|---|
名前 function myfunc % local is an undefined variable local(1); % Errors local = 2; disp(local); end function local(x) disp(x) end | 関数 function myfunc localFcn(1); local = 2; disp(local); end function localFcn(x) disp(x) end | このコードは function myfunc local(1); % local is a function local = 2; disp(local); end function local(x) disp(x) end |
明示的な宣言のない識別子は変数として扱われないことがある
R2019b 以降、MATLAB® ではプログラム内の変数の識別にインデックス演算子を使用しません。以前は、明示的な宣言のない識別子は、コロン、end
、または中かっこでインデックス付けされた場合、変数として扱われました。たとえば、x(a,b,:)
、x(end)
、x{a}
において x
は変数として扱われました。
以下のコードを考えます。コロンのインデックスがあるため、MATLAB で x
は変数として扱われていました。R2019b 以降、パス上に同名の関数が存在する場合、MATLAB では x
を関数として扱います。
function myfunc load data.mat; % data.mat contains variable x disp(x(:)) end
x
を関数ではなく data.mat
の変数として使用する場合は、その旨を明示的に宣言します。同様に、識別子 x
をスクリプトから取得した変数として使用するには、そのスクリプトを呼び出す前に宣言します。この新しい動作は、関数 sim
、eval
、evalc
、および assignin
で変数が暗黙的に導入された場合にも適用されます。
次の表は、コードの更新方法の例をいくつか示しています。
更新前 | 更新後 |
---|---|
function myfunc load data.mat; disp(x(:)) end | function myfunc load data.mat x; disp(x(:)) end |
function myfunc2 myscript; % Contains variable x disp(x(:)) end | function myfunc2 x = []; myscript; disp(x(:)) end |
変数は、親関数と入れ子関数の間で暗黙的に共有できない
R2019b 以降、識別子が親関数内で変数として明示的に宣言されている場合にのみ、識別子を入れ子関数とその親関数間で変数として共有できます。
たとえば以下のコードでは、myfunc
内の識別子 x
は入れ子関数内の変数 x
とは異なります。x
がパス上の関数である場合、MATLAB は myfunc
内の x
を関数として扱い、コードを実行します。そうでない場合、MATLAB はエラーをスローします。
function myfunc nested; x(3) % x is not a shared variable function nested x = [1 2 3]; end end
以前のリリースでは、x
がパス上の関数である場合、MATLAB はこれを myfunc
内では関数として扱い、nested
内では変数として扱いました。x
がパス上の関数ではない場合、MATLAB は myfunc
と nested
の間で共有される変数として扱いました。その結果、コードの出力はパスの状態に依存することになりました。
親関数と入れ子関数間で共有される変数として識別子を使用するには、コードの更新が必要な場合があります。たとえば、親関数内で識別子を空の配列に初期化できます。
更新前 | 更新後 |
---|---|
function myfunc nested; x(3) function nested x = [1 2 3]; end end | function myfunc x = []; nested; x(3) function nested x = [1 2 3]; end end |
ワイルドカードベースのインポートでの優先順位の変更
R2019b 以降、ワイルドカードベースのインポートによりインポートされた関数は、変数、入れ子関数、およびローカル関数より優先順位が低くなります。R2019a 以前は、関数内のインポートは、ローカル関数や入れ子関数より優先されました。
たとえば次のコードでは、ステートメント local()
は、ワイルドカードベースのインポートで pkg1.local
ではなく myfunc/local
を呼び出します。ステートメント nest()
は pkg1.nest
ではなく myfunc/nest
を呼び出します。
R2019b 以降 | R2019a 以前 |
---|---|
function myfunc % Import includes functions local and nest import pkg1.* local() % Calls myfunc/local function nest end nest(); % Calls myfunc/nest end function local end | function myfunc % Import includes functions local and nest import pkg1.* local() % Calls pkg1.local and % displays warning since R2018a function nest end nest(); % Calls pkg1.nest end function local end |
import
の検索結果で、ワイルドカード文字 (*
) を含むステートメントを探してください。
完全修飾のインポート関数は、入れ子関数と同じ名前をもつことができない
R2019b 以降、完全修飾インポートが同じスコープ内の入れ子関数と名前を共有する場合、エラーがスローされます。
R2019b 以降 | 更新されたコード | R2019a 以前 |
---|---|---|
この関数は同じスコープ内の入れ子関数と名前を共有するためエラーになります。 function myfunc import pkg.nest % Errors nest(); function nest end end | 関数 function myfunc import pkg.nest nest(); function newNest end end | この関数は関数 function myfunc import pkg.nest nest(); % Calls pkg.nest function nest end end |
インポートされた関数 function myvarfunc import pkg.nest % Errors nest = 1 end | 変数 function myvarfunc import pkg.nest % Errors thisNest = 1 end | この関数は変数 function myvarfunc import pkg.nest nest = 1 % Modifies variable nest and % displays warning since R2018a end |
完全修飾のインポートは、同名の外部スコープ定義より優先される
R2019b 以降、完全修飾インポートは常に、同名の外部スコープ定義より優先されます。R2019a 以前は、外部スコープ内の識別子よりも優先される完全修飾インポートは無視されました。
R2019b 以降 | 更新されたコード | R2019a 以前 |
---|---|---|
ローカル関数 function myfunc x = 1; function nest % Import function x import pkg1.x % Calls pkg1.x x() end end | 変数 function myfunc x = 1; nest(x) function nest(x1) % Import function x import pkg1.x % Calls pkg1.x with % variable x1 x(x1) end end | このコードでは、関数 function myfunc x = 1; function nest % Import function x import pkg1.x % x is a variable x() end end |
インポートが見つからない場合のエラー処理
R2019b 以降、Java® の有無に関係なく、解決できない完全修飾インポートはエラーをスローします。R2019a 以前は、-nojvm
オプションを指定して MATLAB を起動したかどうかによって、MATLAB の動作が異なりました。エラー メッセージをカスタマイズするために javachk
や usejava
などの関数は使用しないでください。
R2019b 以降 | 更新されたコード | R2019a 以前 |
---|---|---|
function myfunc import java.lang.String % Errors if ~usejava('jvm') % Statement never executes disp('This function requires Java'); else % Do something with Java String class end end |
function myfunc import java.lang.String % Errors % Do something with java String class end |
function myfunc import java.lang.String if ~usejava('jvm') % Display message disp('This function requires Java'); else % Do something with Java String class end end |
入れ子関数は親関数から import ステートメントを継承する
R2019b 以降、入れ子関数は親関数から import
ステートメントを継承します。R2019a 以前は、入れ子関数は親関数から import ステートメントを継承しませんでした。
R2019b 以降 | R2019a 以前 |
---|---|
function myfunc % Package p1 has functions plot and bar import p1.plot import p1.* nest function nest plot % Calls p1.plot bar % Calls p1.bar end end | function myfunc % Package p1 has functions plot and bar import p1.plot import p1.* nest function nest plot % Calls plot function on path bar % Calls bar function on path end end |
複合名解決の優先順位の変更
R2019b 以降、MATLAB は異なったやり方で複合名を解決します。複合名はドットでつながれた複数の部分で構成されており (たとえば、a.b.c
)、パッケージ メンバーの参照に使用できます。R2019b では、MATLAB は最も長く一致する接頭辞を優先することで、複合名を解決します。以前のリリースでは、優先順位はより複雑な一連の規則に従っていました。
たとえば、パッケージ pkg
に、静的メソッド bar
をもつクラス foo
と、関数 bar
をもつサブパッケージ foo
が含まれているとします。
+pkg/@foo/bar.m % bar is a static method of class foo +pkg/+foo/bar.m % bar is a function in subpackage foo
R2019b では、which pkg.foo.bar
の呼び出しはパッケージ関数へのパスを返します。
which pkg.foo.bar
+pkg/+foo/bar.m
以前は、パッケージとクラスが同じ名前をもつ場合、静的メソッドがパッケージ関数より優先されました。
無名関数は解決済みの識別子と未解決の識別子を含むことができる
R2019b 以降、無名関数に解決済みの識別子と未解決の識別子の両方を含めることができます。以前のリリースでは、無名関数内のいずれかの識別子が作成時に解決されなかった場合、その無名関数内のすべての識別子が未解決になりました。
R2019b 以降 | R2019a 以前 |
---|---|
無名関数を評価するために、MATLAB は、 function myfun myscript; % Includes x = 1 and lf = 10 f = @()lf(x); f() % Displays 'Inside lf' end % Local function to myfun function lf(y) disp('Inside lf'); end | MATLAB は function myfun myscript; % Includes x = 1 and lf = 10 f = @()lf(x); f() % Displays 10 end % Local function to myfun function lf(y) disp('Inside lf'); end |