Guideline 5: Never run anything directly in a super procedure
- Last Updated: September 12, 2023
- 3 minute read
- OpenEdge
- Version 13.0
- Documentation
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.
- Initialization code in the object procedure runs
startMeUp, but runs it explicitlyINthe handle of its super procedure, rather than letting the interpreter do this implicitly. - The AVM does what it is told and runs
startMeUp IN hSuper. - Because
startMeUpwas specifically runINhSuper, thenhSuperbecomes theTARGET-PROCEDURE, the handle of the procedure in which the routine was originally invoked. - Thus, any reference to
TARGET-PROCEDUREcauses the interpreter to search the super procedure itself for the routine to execute. - The AVM never finds and executes the version of
nowDoThisback 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.
- 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
GLOBALvariable (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. - 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 referenceTARGET-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. - 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.