エラーの解決: 静的なワークスペースへの変数追加の試み
問題
入れ子関数と無名関数のワークスペースは静的です。つまり、関数内で使用される変数はすべて、コードのテキスト内に存在していなければなりません。
無名関数、入れ子関数あるいは入れ子関数が含まれている関数の静的ワークスペースに変数を動的に追加しようとすると、MATLAB® で以下のようなエラーが発生します。
Attempt to add variable to a static workspace.
ベース ワークスペースと関数ワークスペースの差異の詳細については、ベース ワークスペースと関数ワークスペースを参照してください。入れ子関数の詳細については、入れ子関数を参照してください。
考えられる解決策
変数を事前に宣言
変数を静的ワークスペースに動的に追加することを回避する 1 つの方法は、値をその変数に動的に代入する前に、コード内で変数を明示的に宣言することです。そうすることで、変数名が MATLAB に表示されるようになり、静的ワークスペースを構成する固定の変数セットにその名前が含まれます。
たとえば、makeX.m
というスクリプトで変数 X
に値を動的に代入するとします。makeX
を呼び出し、"かつ" X
を明示的に宣言する関数は、X
が関数ワークスペースにあるため、動的追加によるエラーを回避します。
変数を宣言する一般的な方法は、その値を空の配列に初期化することです。
function noerror nestedfx function nestedfx X = []; makeX end end
eval
、evalin
、または assignin
を使用して入れ子関数内で新しい変数を代入
eval
、evalin
、または assignin
を使用して入れ子関数内で新しい変数を代入するとエラーが生成されます。
function staticWorkspaceErrors function nest % This will error since x is not declared outside of the eval eval("x=2"); end end
可能であれば、これらの関数の使用を回避します。関数 eval の代替方法を参照してください。回避できない場合は、親関数内で変数を明示的に宣言します。
function noStaticWorkspaceErrors x = []; function nest % This will not error since 'x' is declared outside of the eval eval("x=2"); end end
MATLAB スクリプトを使用して新しい変数を入れ子関数で代入
入れ子関数内で変数を作成する MATLAB スクリプトを呼び出すとエラーが生成されます。下の例のスクリプト scriptThatIntroducesZ
には、変数 z
に値を代入するコードが含まれています。z
に代入されていることがコードで明示的に宣言されていないため、エラーがスローされます。
function staticWorkspaceErrors function nest % This will error since 'z' is not declared outside of this script scriptThatIntroducesZ end end
エラーを回避するには、値を代入するスクリプトを呼び出す前に、関数内でその変数を宣言します。
function noStaticWorkspaceErrors function nest % This will not error since 'z' is declared outside of the script z = []; scriptThatIntroducesZ end end
あるいは、スクリプトを関数に変換し、z
をその出力引数にします。この方法により、コードもわかりやすくなります。
関数 load
で明示的な変数名を使用
変数名を明示的に指定せずに、load
を使用して入れ子関数内で変数を代入すると、エラーが生成されます。下の例では、変数 Y
を含む MAT ファイルを読み込むために load
が使用されています。Y
に代入されていることがコードで明示的に宣言されていないため、エラーがスローされます。
function staticWorkspaceErrors function nest % This will error since var Y is not explicitly specified load MatFileWithVarY end end
エラーを回避するには、代わりに変数名を関数 load
への入力として指定します。
function noStaticWorkspaceErrors function nest % This will not error since variables 'x' and 'y' are specified load MatFileWithVarX x y = load('MatFileWithVarY','y'); end end
あるいは、関数 load
からの出力を構造体配列に代入します。
入れ子関数の MATLAB デバッガーでの変数の代入
デバッグ中、入れ子関数で停止している場合は、デバッグ コマンド プロンプトを使用して変数を追加することはできません。変数をベース ワークスペースに代入します。このワークスペースは静的ではありません。
K>> assignin('base','X',myvalue)
無名関数での変数の代入
無名関数には変数の代入を含めることはできません。無名関数が呼び出されると、エラーがスローされます。
% This will error since 'x' is being assigned inside % the anonymous function @()eval("x=2")
変数の代入が必要とされない方法で関数を書き直します。
xEquals2 = @()2; x = xEquals2()
x = 2