You can nest one module definition within another. Each nested module must be completely contained inside the parent module. When you nest modules, it is a good idea to indent the statements relative to the nesting level, as shown in the following example:
start ModA; start ModB; x = 1; finish ModB; run ModB; finish ModA; run ModA;
In this example, SAS/IML software starts parsing statements for a module called ModA. In the middle of this module, it recognizes the start of a new module called ModB. It parses ModB until it encounters the first FINISH statement. It then finishes parsing ModA. Each module is defined independently of the others. The previous statements are equivalent to the following:
start ModB; x = 1; finish ModB; start ModA; run ModB; finish ModA; run ModA;
In particular, you can call the ModB module from the program’s main scope. Although it looks as though ModB might be “local” to ModA, that is not the case. There is no such thing as a local module. All modules are defined at global scope.
Consider the following example of calling one module from another module:
proc iml; start Mod5(a,b); c = a+b; d = a-b; run Mod6(c,d); print "In Mod5:" c d; finish; start Mod6(x,y); x = x#y; finish; run Mod5({1 2}, {3 4});
When one module calls another, you can pass in any symbol defined in the scope of the calling module. In the previous example,
the Mod5 module calls the Mod6 module and passes in the local variables c
and d
. The Mod6 module multiplies its arguments and overwrites the first argument, as shown in Figure 6.11.
The variables in the local symbol table of Mod5 are available to pass into Mod6. If Mod6 changes the values of an argument,
those values are also changed in the environment from which Mod6 was called. For the previous example, this means that the
local variable c
is modified by Mod6.
If a module has no arguments, it can access variables in the environment from which it is called. For example, consider the following modules:
x = 123; start Mod7; print "In Mod7:" x; finish; start Mod8(p); print "In Mod8:" p; run Mod7; finish; run Mod8(x);
In this example, module Mod7 is called from module Mod8. Therefore, the variables available to Mod7 are those defined in the
scope of Mod8. There is no variable named x
in the environment of Mod8. Therefore an error occurs on the PRINT statement in Mod7, as shown in Figure 6.12. An error would not occur if you call Mod7 from the main scope, because x
is defined at main scope.
Figure 6.12: Error Message When a Variable Is Not Defined in a Module
NOTE: IML Ready |
NOTE: Module MOD7 defined. |
NOTE: Module MOD8 defined. |
ERROR: Matrix x has not been set to a value. |
statement : PRINT at line 1649 column 4 |
traceback : module MOD7 at line 1649 column 4 |
module MOD8 at line 1654 column 4 |
NOTE: Paused in module MOD7. |