Nesting Modules

You can nest one module within another. You must make sure that each nested module is completely contained inside the parent module. Each module is defined independently of the others. 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. Thus, it behaves the same as if ModB were parsed prior to ModA, as follows:

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. It is not the case that ModB is a "local module" known only to module ModA. There is no such thing as a local module.

Calling a Module from Another Module

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.9.

Figure 6.9 Output from Nested Modules
  c   d  
In Mod5: -8 -12 -2 -2

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.10. An error would not occur if you call Mod7 from the main scope, because x is defined at main scope.

Figure 6.10 Error Message When a Variable Is Not Defined in a Module
line
 
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 1550 column 4                                        
 traceback : module MOD7 at line 1550 column 4                                  
             module MOD8 at line 1555 column 4                                  
 
NOTE: Paused in module MOD7.