11.2 関数の定義
最も単純な形式では、nameという名前の関数の定義は 次のようになります。
function name body endfunction
有効な関数名は有効な変数名と同様です。つまり、文字、数字、アンダースコアのシーケンスであり、数字で始まってはなりません。関数は変数と同じ名前のプールを共有します。
関数本体はOctave ステートメントで構成されます。関数が実際に何をすべきかを記述するため、定義の中で最も重要な部分です。
たとえば、実行すると端末のベルを鳴らす関数を次に示します (実行可能であると仮定します)。
function wakeup
printf ("\a");
endfunction
ステートメントprintf(入力と出力を参照)は、単にOctaveに文字列を印刷するように指示します"\a"。特殊文字'\a' は警告文字 (ASCII 7) を表します。文字列を参照してください。
この関数が定義されたら、関数名を入力して Octave に評価を依頼できます。
通常、定義した関数に何らかの情報を渡す必要があります。Octaveで関数にパラメータを渡す構文は次のとおりです。
function name (arg-list) body endfunction
ここで、arg-list は関数の引数のコンマ区切りリストです。関数が呼び出されると、引数名は呼び出しで指定された引数値を保持するために使用されます。引数リストは空の場合もあり、その場合、この形式は上記の形式と同等になります。
ベルを鳴らすと同時にメッセージを印刷するには、 wakeup次のように変更します。
function wakeup (message)
printf ("\a%s\n", message);
endfunction
この関数を次のような文で呼び出すと
wakeup ("Rise and shine!");
すると、Octaveは端末のベルを鳴らし、次のメッセージを表示します。起きて輝け!' の後に改行文字 ('\n' をステートメントの最初の引数に含めますprintf)。
ほとんどの場合、定義した関数から何らかの情報を取得する必要があります。単一の値を返す関数を作成するための構文は次のとおりです。
function ret-var = name (arg-list) body endfunction
シンボルret-varは、関数によって返される値を保持する変数の名前です。関数が値を返すためには、この変数は関数本体の終了前に定義する必要があります。
関数の本体で使用される変数は、関数に対してローカルです。arg -listおよびret-varで指定された変数も関数に対してローカルです。関数内でグローバル変数にアクセスする方法については、 「グローバル変数」を参照してください。
たとえば、ベクトルの要素の平均を計算する関数を次に示します。
function retval = avg (v) retval = sum (v) / length (v); endfunction
avg代わりにこのように 書いていたら、
function retval = avg (v) if (isvector (v)) retval = sum (v) / length (v); endif endfunction
そして、ベクトルではなく行列を引数として関数を呼び出すと、Octave は次のようなエラー メッセージを出力します。
エラー: 代入の右側の値が未定義です
なぜなら、文の本体はif一度も実行されておらず、 retval定義もされていないからです。このようなわかりにくいエラーを防ぐには、戻り変数に常に値があることを常に確認し、問題が発生したときに意味のあるエラー メッセージを生成することをお勧めします。たとえば、avg次のように記述することもできます。
function retval = avg (v)
retval = 0;
if (isvector (v))
retval = sum (v) / length (v);
else
error ("avg: expecting vector argument");
endif
endfunction
この関数にはまだ問題が 1 つ残っています。引数なしで呼び出された場合はどうなるでしょうか。追加のエラー チェックがなければ、Octave はおそらくエラー メッセージを出力するでしょうが、これはエラーの原因を追跡するのにはあまり役立ちません。このようなエラーを検出できるようにするために、Octave は各関数に と呼ばれる自動変数を提供します nargin。関数が呼び出されるたびに、 はnargin関数に実際に渡された引数の数に自動的に初期化されます。たとえば、関数を次のように書き直すことができます avg。
function retval = avg (v)
retval = 0;
if (nargin != 1)
usage ("avg (vector)");
endif
if (isvector (v))
retval = sum (v) / length (v);
else
error ("avg: expecting vector argument");
endif
endfunction
Octave は、.m ファイル コードで記述された関数が予想よりも多くの引数で呼び出された場合、自動的にエラーを報告します。関数が呼び出される引数が少なすぎる場合、Octave は自動的にエラーを報告しません。これは、関数は一般にデフォルトの引数を持つ可能性があるものの、値が与えられていない変数を使用しようとするとエラーが発生するためです。関数は、呼び出される引数をチェックして、このような問題を回避し、よりコンテキスト固有のエラー メッセージを提供できます。
: n = nargin ()
: n = nargin (fcn)
関数への入力引数の数を報告します。
関数内から呼び出され、関数に渡された引数の数を返します。最上位レベルでは、Octave に渡されたコマンドライン引数の数を返します。
オプションの引数fcn (関数名またはハンドル) を指定して呼び出された場合は、関数が受け入れることができる引数の宣言された数を返します。
fcnの最後の引数がvararginの場合、返される値は負になります。たとえば、unionsetsの関数は次のように宣言されます。
function [y, ia, ib] = union (a, b, varargin)
そして
nargin ("union")
⇒ -3
プログラミングノート:narginコンパイルされた関数では動作しません (.oct組み込み関数や動的にロードされる関数などの関数(ファイルなど)です。
nargout、narginchk、varargin、inputnameも参照してください。
: namestr = inputname (n)
: namestr = inputname (n, ids_only)
呼び出し関数の n番目の引数の名前を返します。
引数が単純な変数名でない場合は、空の文字列を返します。返される例としては、""数値 ( 5.1)、式 ( y/2)、セルまたは構造のインデックス (c{1}または) などがあります。 s.field
inputname関数内でのみ役立ちます。コマンド ラインまたはスクリプト内で使用すると、常に空の文字列が返されます。
デフォルトでは、 n番目の引数が有効な変数名でない場合は空の文字列を返します。オプションの引数ids_onlyが false の場合は、有効な変数名でない場合でも引数のテキストを返します。これは Octave の拡張機能であり、入力が複雑な式であっても、プログラマーが関数が呼び出された方法を正確に表示できます。
nargin、narginchkも参照してください。
: val = silent_functions ()
: old_val = silent_functions (new_val)
: old_val = silent_functions (new_val, "local")
関数からの内部出力を抑制するかどうかを制御する内部変数を照会または設定します。
このオプションを無効にすると、Octave はセミコロンで終了していない関数本体内の式を評価することによって生成された結果を表示します。
オプションを使用して関数内から呼び出されると"local"、関数とそれが呼び出すサブルーチンに対して変数がローカルに変更されます。関数を終了すると、元の変数値が復元されます。