定义程序

 
 
 

全局程序

一旦定义了全局程序,您可以在任意位置调用它:从任意脚本文件、在任意函数中、或从命令行。全局程序声明的常规形式如下所示:

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");}

这对于生成对其他程序起作用的“辅助对象”程序非常有用。您可以对其他使用您的脚本的人员仅显示一个或两个全局程序,而隐藏辅助对象代码。

不能在“脚本编辑器”(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 程序,该程序将始终存在且无法删除。无论该程序是显式还是隐式创建都如此。通过使用 proc 指令(例如,proc foo(){})显式创建程序 foo。可通过执行下列任一操作隐式创建尚未显式创建的程序 foo

MEL 程序与插件命令

通常,所有来自插件的程序和命令都应具有唯一名称。如果使用相同名称,比如说 foo,对于程序和插件命令,将优先考虑程序。例如,如果同时具有:

  • 名为 foo 的隐式(或显式)定义的程序
  • 带有名为 foo 的命令的已加载插件 fooCmd

然后执行 whatIs 命令,它将仅报告程序。

如果仅有隐式定义的 foo,仍可加载 fooCmd 插件并使用其 foo 命令,即使 whatIs foo 将仅报告程序。但是,如果具有显式定义的 foo 作为 MEL 程序(例如,proc foo(){}),则根本不能使用插件的 foo 命令。

解决方案

通过禁止 MEL 分析器将 foo 视为程序,可以解决隐式定义在其他程序定义中嵌入的程序 foo 的问题。通过将 foo 的用法嵌入到字符串,然后使用该字符串调用 eval,可以执行该操作,如下所示。

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

如果 foo 是名为 fooCmd 的插件中定义的命令,应先检查 foo 是否存在,以防在插件未加载时调用 bar()。在这种情况下,即使 foo -h 已作为传递到 eval 语句的字符串,尝试执行 foo -h 仍将生成错误消息,但仍会隐式定义名为 foo 的用户程序。