Main Content

エラーの解決: 静的なワークスペースへの変数追加の試み

問題

入れ子関数と無名関数のワークスペースは静的です。つまり、関数内で使用される変数はすべて、コードのテキスト内に存在していなければなりません。

無名関数、入れ子関数あるいは入れ子関数が含まれている関数の静的ワークスペースに変数を動的に追加しようとすると、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

evalevalin、または assignin を使用して入れ子関数内で新しい変数を代入

evalevalin、または 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

関連するトピック