全局程序
一旦定义了全局程序,您可以在任意位置调用它:从任意脚本文件、在任意函数中、或从命令行。全局程序声明的常规形式如下所示:
global proc
return_type
procedure_name
(
arguments
) {
MEL_statements
}
global 关键字使新程序在任意位置可用。
proc 关键字指示您正在定义程序。
可以在 proc 后为程序的返回类型添加关键字。例如,如果程序返回一个整数,请键入 int。如果程序不返回值,可以忽略。
程序的名称。
参数列表,包括在括号内,且之间用逗号分隔。每个参数都是一个前面带有其类型(例如 string)的变量名(以 $ 开头)。
要在调用程序时执行的代码块。
返回值
如果为程序指定了返回类型,则必须在程序代码块中的某位置使用 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! "; } 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. "; }
局部程序
如果在程序声明的开头不使用 global 关键字,则该程序对于在其中定义它的文件是局部的。
// This is a local procedure // that is only visible to the code in this file. proc red5() {print("red5 standing by... ");}
这对于生成对其他程序起作用的“辅助对象”程序非常有用。您可以对其他使用您的脚本的人员仅显示一个或两个全局程序,而隐藏辅助对象代码。
不能在“脚本编辑器”(Script Editor)中定义局部程序。它们仅在外部脚本文件中可用。
注意MEL 不允许您提前引用局部范围的程序。局部范围内的程序定义必须在被调用之前显示。例如,在名为 noForwardRef.mel 的文件中,引用局部程序之前定义这些程序。
proc myLocalProc() { print "In myLocalProc() " ; } proc anotherLocalProc() { print "In anotherLocalProc() " ; myLocalProc; } global proc noForwardRef() { print "Calling anotherLocalProc() " ; anotherLocalProc; }
程序不能是未定义的
一旦定义了 MEL 程序,该程序将始终存在且无法删除。无论该程序是显式还是隐式创建都如此。通过使用 proc 指令(例如,proc foo(){})显式创建程序 foo。可通过执行下列任一操作隐式创建尚未显式创建的程序 foo:
尝试以交互方式将其用作程序,例如,在“脚本编辑器”(Script Editor)中:
foo; // Error: line 1: Cannot find procedure "foo". //
将其用作其他程序的定义内的程序:
proc bar() { 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 的用户程序。
,