プロシージャを定義する

グローバル プロシージャ

グローバル プロシージャを定義すると、スクリプト ファイルから、関数の中で、コマンド ラインからというように、どこからでもグローバル プロシージャをコールすることができます。グローバル プロシージャを宣言する場合の一般的な形式は次の通りです。

global proc 
return_type
procedure_name
(
arguments
) {
MEL_statements 
}

戻り値

プロシージャの戻り値の型を指定する場合、値を返すためにプロシージャのコード ブロックのどこかで return 演算子を使用する必要があります。

global proc float square(float $x) {
	return $x * $x;
}
square(5.0);
25

プロシージャの戻り値の型を指定しない場合(プロシージャが値を返さないことを示す)にできるのは、戻り値をつけずに return 演算子を指定することだけです。このコンテキストで return 演算子を使用した場合、これは関数ブレイクの役割を果たします。

// This does not work. 
global proc add5(int $x) {return $x+5;}; 
// Error: global proc cc(int $x) {return $x+5;}; // 
// Error: This procedure has no return value. //
// This works. 
global proc add5(int $x) {return;};" 

次にプロシージャ宣言の例をいくつか示します。

global proc string sayHi() {
	return "Hello!\n";
}
global proc float square(float $x) {
	return $x * $x;
}
global proc int max(int $a, int $b) {
	if ($a > $b) {
		return $a;
	} else 
		return $b;
}
global proc msg() {
	print "This proc has no return value.\n";
}

ローカル プロシージャ

プロシージャ宣言の最初で global キーワードを省略すると、プロシージャは定義されたファイル内でローカルになります。

// This is a local procedure
// that is only visible to the code in this file.
proc red5() {print("red5 standing by...\n");}

これは、他のプロシージャで使用される「ヘルパ」プロシージャを作成するのに非常に便利です。公開するグローバル プロシージャは 1 つか 2 つだけにして、スクリプトを使用する他の人々にはヘルパ コードが見えないようにすることができます。

スクリプト エディタ(Script Editor)でローカル プロシージャを定義することはできません。これらは、外部スクリプト ファイルのみで使用可能です。

注: MEL でローカルにスコープされたプロシージャを前方に参照することは許可されていません。ローカルにスコープされたプロシージャの定義はコールする前に現わさなければいけません。例えば、noForwardRef.mel というファイルでは、ローカル プロシージャが参照される前に定義します。

proc myLocalProc() { print "In myLocalProc()\n" ; } proc anotherLocalProc() { print "In anotherLocalProc()\n" ; myLocalProc; } global proc noForwardRef() { print "Calling anotherLocalProc()\n" ; anotherLocalProc; }

プロシージャを未定義にはできない

MEL プロシージャは、一旦定義すると常に存在するものであり削除することはできません。これは、明示的に作成した場合でも黙示的に作成した場合でも同じです。プロシージャ fooproc 命令(たとえば、proc foo(){})を使用して明示的に作成されます。明示的に作成されていないプロシージャ foo は次のいずれかの方法で黙示的に作成できます。

MEL プロシージャとプラグインコマンド

一般的に、プラグインのプロシージャとコマンドの名前はすべて一意です。同じ名前を使用する、たとえば foo をプロシージャとプラグイン コマンドの両方に使用すると、そのプロシージャはプロシージャを取ることになります。たとえば、次の両方があるとします。

  • 黙示的に(または明示的に)定義した foo という名前のプロシージャ
  • foo という名前のコマンドを持つ fooCmd というロードされたプラグイン

ここで、whatIs コマンドを実行した場合、レポートされるのはプロシージャに関してのみです。

黙示的に定義した foo のみの場合は、whatIs foo がプロシージャのみに関してレポートするとしても、fooCmd プラグインをロードしてその foo コマンドを使用できます。ただし、MEL のプロシージャとして明示的に定義した foo (たとえば、proc foo(){})がある場合、プラグインの foo コマンドを使用することはできません。

解決方法

MEL パーサが foo をプロシージャとして扱わないようにすることで、プロシージャ foo を黙示的に定義して別のプロシージャの定義内に埋め込む問題を回避できます。これには、文字列に foo の使用を埋め込み、以下のようにその文字列で eval をコールします。

proc bar()
{
   if( `exists foo`){
    string $cmd = "foo -h";
    eval($cmd);
    }
}
注:

foofooCmd というプラグインに定義されたコマンドである場合、まず foo が存在するかどうかを確認し、プラグインをロードしない状態で bar() がコールされないようにします。この場合、eval 文に渡した文字列と共に foo -h を実行しようとするとエラー メッセージは表示されますが、foo というユーザ プロシージャが黙示的に定義されます。