Super procedures should generally not have a super procedure stack of their own. The stack of super procedures (if there is more than one) for an application object should be defined by the object procedure itself. This is done by always using the SEARCH-TARGET keyword in the ADD-SUPER-PROCEDURE() methods. This gives you maximum flexibility to define and modify the stack as needed without the individual super procedures having to be aware of each other.

An example can help clarify how this works. In this figure, you have an application object procedure and two super procedures from which it inherits standard behavior.
Figure 1. An object procedure and two super procedures
This is accomplished by running all the procedures persistent and then executing these statements from the object procedure:
THIS-PROCEDURE:ADD-SUPER-PROCEDURE(hTop, SEARCH-TARGET).
THIS-PROCEDURE:ADD-SUPER-PROCEDURE(h2nd, SEARCH-TARGET).
The object procedure executes the following statement:
RUN startMeUp.

The ABL interpreter searches for an internal procedure named startMeUp first in the object procedure itself, then in the code of the last super procedure added (h2nd), and finally in the code of the first super procedure added (hTop). There is an implementation of this internal procedure in all three places and they are all intended to run in sequence. The code in the top super procedure is the most general and is executed last. The code in the 2nd super procedure is more specific and is executed second. And the code in the object procedure itself is specific to that particular object and is executed first. This figure shows the sequence of control that takes place at run time.

Figure 2. Super procedure stack execution
The code executes as follows:
  1. The interpreter locates the implementation of startMeUp in the object procedure instance and runs it. The startMeUp procedure executes its application-specific code. The RUN SUPER statement causes the interpreter to search up the super procedure stack for another version of the same internal procedure name.
  2. The interpreter searches the instance of the 2nd super procedure.
  3. The interpreter finds and executes the version of startMeUp in the 2nd super procedure. It runs some code and then does another RUN SUPER. Here is where the use of SEARCH-TARGET becomes significant. If you did not specify this keyword on the ADD-SUPER-PROCEDURE() method, the default would be SEARCH-SELF, which means that the RUN SUPER statement in the 2nd super procedure would cause the interpreter to search up the 2nd super procedure’s own super procedure stack for another version of startMeUp. Because the 2nd super procedure has no super procedures of its own, the interpreter would find nothing and the RUN SUPER statement would return an error.
  4. Instead, the use of SEARCH-TARGET causes the interpreter to go back to the object procedure where startMeUp was run in the first place and continue to search up its stack. This causes it to search the top super procedure.
  5. Finally, the interpreter locates and executes the top-most version of startMeUp.
Now compare this with what is required if you do not use SEARCH-TARGET. For the RUN SUPER statement in the 2nd super procedure to execute properly, you need a double set of super procedure definitions, with this statement in the initialization code for the second super procedure:
THIS-PROCEDURE:ADD-SUPER-PROCEDURE(hTop).

This figure diagrams this code.

Figure 3. Super procedure stack execution without SEARCH-TARGET

Now the RUN SUPER statement in the 2nd super procedure causes the interpreter to search up its own stack (4), finding the top-level code to execute (5).

So what’s the problem with this approach? This potentially complicates the application considerably. Each super procedure must have its own initialization code to establish its own procedure stack, which must duplicate that portion of the object procedure’s stack above itself (somewhat akin to the old song The Twelve Days of Christmas, each super procedure moving down the chain from the top must duplicate the chain from itself on up). This is not only more work than the other approach, but it also makes it more difficult to build any flexibility into the scheme. What if some object procedure wants to have a different procedure stack? This is not really possible because the super procedures themselves duplicate the stack and therefore make it almost impossible to change from object procedure to object procedure. Or what if an object procedure wants to insert an additional super procedure into the stack conditionally? This also can’t really be done. Simply put, unless there are specific circumstances dictating otherwise, it is the best practice always to use the SEARCH-TARGET keyword.