As discussed earlier, the whole mechanism of using TARGET-PROCEDURE as a means to identify the handle of the object on whose behalf an action is being taken depends on the routine that executes the action being invoked IN the object procedure. The ABL interpreter then takes care of the work of locating the routine in a super procedure and executing it there. This works properly only if application code never runs any routines directly in a super procedure handle. The example shown helps to illustrate this point.

Figure 1. Running a procedure within a super procedure
Here’s the (undesired) sequence of events:
  1. Initialization code in the object procedure runs startMeUp, but runs it explicitly IN the handle of its super procedure, rather than letting the interpreter do this implicitly.
  2. The AVM does what it is told and runs startMeUp IN hSuper.
  3. Because startMeUp was specifically run IN hSuper, then hSuper becomes the TARGET-PROCEDURE, the handle of the procedure in which the routine was originally invoked.
  4. Thus, any reference to TARGET-PROCEDURE causes the interpreter to search the super procedure itself for the routine to execute.
  5. The AVM never finds and executes the version of nowDoThis back in the object itself.

For the super procedure to get back to the object procedure, it needs to use the SOURCE-PROCEDURE built-in function, but even this won’t always work if the original RUN statement is located anywhere except in the actual source code for the object procedure. So, the whole relationship between the object procedure and its supporting super procedure becomes messed up, and you can expect confusing results.

Note that even in a case where you are defining a global property in a super procedure, as discussed in the previous section, an object that wants to get at that property value should still do it indirectly, by requesting it from itself, and letting the interpreter locate the routine that supplies the value in the super procedure. This figure shows an example.

Figure 2. Example of a global property in a super procedure
The sequence of events in the figure executes as follows:
  1. The main block of the super procedure defines the value to return to any requesting object procedure, outside the scope of an internal procedure or function. This is not actually an ABL GLOBAL variable (which you should avoid), but because it is effectively global to all procedures using this super procedure, in the sense that its value is persistent across calls from many objects, you can use a naming convention of preceding the name with a g to make it clear that it’s defined at the scope of the whole super procedure.
  2. An object procedure requests the value by executing a function that is defined in the super procedure. But the function is invoked in the object procedure itself, not directly in the handle of the super procedure. The interpreter locates the function in the super procedure and executes it there. Invoking the function directly in the super procedure by using the syntax DYNAMIC-FUNCTION (‘valueEverybodyNeeds’ IN hSuper) is a bad idea. First, because it messes up any attempt by the function code to reference TARGET-PROCEDURE, and, second, because it hard-codes into the object procedure the fact that the supporting function is implemented in this particular super procedure. This makes the application more difficult to maintain.
  3. The supporting function returns the value, which is then used by the object procedure.

This simple example presumes that there is a function prototype defined in the object procedure so that the compiler knows how to evaluate the function.