Defining procedures

 
 
 

Global procedures

Once you define a global procedure, you can call it anywhere: from any script file, within any function, or from the command line. The general form of a global procedure declaration is:

global proc 
 return_type
 procedure_name
(
 arguments
) {
 MEL_statements 
}

Return values

If you specify a return type for a procedure, then you must use a return operator somewhere in the procedure’s code block to return a value.

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

If you don’t specify a return type for a procedure (indicating that the procedure will not return a value), then you can only specify the return operator without a return value. Use of a return operator in this context serves as a function break.

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

Examples

Here are some example procedure declarations:

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

Local procedures

If you leave the global keyword off the beginning of a procedure declaration, the procedure is local to the file in which it is defined.

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

This is very useful for making “helper” procedures that do work for other procedures. You can expose just one or two global procedures, hiding the helper code from other people using your scripts.

You cannot define a local procedure in the Script Editor. They are only available in external script files.

NoteMEL does not allow you to forward reference locally scoped procedures. Locally scoped procedure definitions must appear before they are called. For example, in a file called noForwardRef.mel, define the local procedures before they are referenced.

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

Procedures cannot be undefined

Once you define a MEL procedure, it always exists and cannot be deleted. This is true regardless of whether the procedure was created explicitly or implicitly. A procedure foo is created explicitly by using the proc directive (for example, proc foo(){}). A procedure foo that has not yet been created explicitly can be created implicitly by either:

MEL procedures vs plug-in commands

In general, all procedures and commands from plug-ins should have unique names. If you use the same name, say foo, for both a procedure and a plug-in command, the procedure takes precedence. For example, if you have both:

  • an implicitly (or explicitly) defined procedure called foo
  • a loaded plug-in called fooCmd with a command called foo

and you execute the whatIs command, it will only report on the procedure.

If you have only implicitly defined foo, it is still possible to load the fooCmd plug-in and use its foo command, even though whatIs foo will only report on the procedure. However, if you have explicitly defined foo as a MEL procedure (for example, proc foo(){}), then you won't be able to use the plug-in's foo command at all.

Workaround

You can work around the problem of implicitly defining a procedure foo embedded within another procedure's definition by not letting the MEL parser treat foo as a procedure. You can do this by embedding the usage of foo in a string, and calling eval with that string, as follows.

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

If foo is a command defined in a plug-in called fooCmd, you should first check if foo exists, in case bar() is called with the plug-in unloaded. In that case, trying to execute foo -h, even as a string passed to the eval statement, would generate an error message but still implicitly define a user procedure called foo.