Main Content

ワークスペース間でのデータの共有

はじめに

このトピックでは、ワークスペース間で変数を共有する方法、または次回の関数実行まで変数を存続させる方法について説明します。

ほとんどの場合、関数内で作成された変数はその関数内のみで認識される "ローカル" 変数です。ローカル変数はコマンド ラインや他の関数で使用することができません。ただし、複数の関数やワークスペースでデータを共有する方法はいくつかあります。

ベスト プラクティス: 引数の受け渡し

関数の変数のスコープを拡大する最も安全な方法は関数の入出力引数を使用することで、これによって変数の値を受け渡せるようになります。

たとえば、ある入力値を共有し、これを変更する 2 つの関数 update1 および update2 を作成します。update2 はファイル update1.m にローカル関数として定義するか、独自のファイル update2.m に定義することができます。

function y1 = update1(x1)
   y1 = 1 + update2(x1);

function y2 = update2(x2)
   y2 = 2 * x2;

コマンド ラインから関数 update1 を呼び出して、ベース ワークスペースで変数 Y に代入します。

X = [1,2,3];
Y = update1(X)
Y =
     3     5     7

入れ子関数

入れ子関数は、自身が入れ子になっているすべての関数のワークスペースにアクセスできます。したがって、入れ子関数はたとえばその親関数で定義されている変数 (次の例では x) を使用できます。

function primaryFx
   x = 1;
   nestedFx

   function nestedFx
      x = x + 1;
   end
end

所定の変数が親関数で使用されない場合は、入れ子関数のローカル変数として扱われます。たとえばこのバージョンの primaryFx では、2 つの入れ子関数にそれぞれ独自バージョンの x があり、その相互対話は不可能です。

function primaryFx
   nestedFx1
   nestedFx2

   function nestedFx1
      x = 1;
   end

   function nestedFx2
      x = 2;
   end
end

詳細は、入れ子関数を参照してください。

永続変数

関数内で永続変数を宣言すると、その変数値はひとつの関数呼び出しから次の関数呼び出しまで保持されます。他のローカル変数では、現在の関数を実行している間に限り値が保持されます。永続変数は、他のプログラミング言語における静的変数に相当します。

永続変数は、使用する前に persistent キーワードを使って変数を宣言します。MATLAB® では、永続変数を空行列 [] に初期設定します。

たとえば、findSum.m という名前のファイルに合計の初期値を 0 に設定する関数を定義してから、反復ごとに値を加算していきます。

function findSum(inputvalue)
persistent SUM_X

if isempty(SUM_X)
   SUM_X = 0;
end
SUM_X = SUM_X + inputvalue;

この関数を呼び出す際、SUM_X の値はそれ以降の関数実行でも保持されたままとなります。

関数の永続変数をクリアするには、以下の操作を使用します。

  • clear all

  • clear functionname

  • 関数ファイルの編集

永続変数がクリアされないようにするには、mlock を使用して関数ファイルをロックします。

グローバル変数

グローバル変数は、関数やコマンド ラインからアクセスできる変数です。この変数には、ベース ワークスペースや関数ワークスペースとは別に専用のワークスペースがあります。

ただし、グローバル変数には顕著なリスクが伴います。以下に例を示します。

  • グローバル変数は任意の関数によってアクセスし更新することができます。その変数を使用する他の関数によって、予期しない結果が返される可能性があります。

  • "新しい" グローバル変数に誤って既存のグローバル変数と同じ名前を付けてしまうと、ある関数で使用する値が別の関数で上書きされる可能性があります。このエラーは診断が困難です。

グローバル変数はなるべく慎重に使用してください。

グローバル変数を使用する場合は、ある特定の場所 (関数またはコマンド ライン) でこれらの変数にアクセスする前に、global キーワードを使用して宣言を行ってください。たとえば、falling.m というファイルに新しい関数を作成します。

function h = falling(t)
   global GRAVITY
   h = 1/2*GRAVITY*t.^2;

その後、プロンプトで以下のコマンドを入力します。

global GRAVITY
GRAVITY = 32;
y = falling((0:.1:5)');

2 つのグローバル ステートメントが、関数の内部で利用可能なコマンド プロンプトで GRAVITY に値を割り当てます。ただし、より信頼性の高い代替方法としては、値を入力として受け入れるよう次のように関数を定義し直します。

function h = falling(t,gravity)
   h = 1/2*gravity*t.^2;

その後、プロンプトで以下のコマンドを入力します。

GRAVITY = 32;
y = falling((0:.1:5)',GRAVITY);

別のワークスペースでの評価

関数 evalin と関数 assignin では、コマンドまたは変数名を文字ベクトルから評価し、現在のワークスペースとベース ワークスペースのどちらを使用するかを指定できます。

グローバル変数の場合と同様、これらの関数には既存のデータを上書きしてしまうリスクが伴います。慎重に使用してください。

evalinassignin は、グラフィカル ユーザー インターフェイスでベース ワークスペースに対して評価を行うコールバック関数に使用すると便利なことがあります。たとえば、ベース ワークスペースから変数名を一覧したリスト ボックスを作成します。

function listBox
figure
lb = uicontrol('Style','listbox','Position',[10 10 100 100],...
              'Callback',@update_listBox);
update_listBox(lb)

function update_listBox(src,~)
vars = evalin('base','who');
src.String = vars;

その他のプログラミング用途については、引数の受け渡しおよび関数 eval の代替方法に記載されている手法を検討してください。

関連するトピック