Determine the calling procedure

Note

This article was originally posted to the AIMMS Tech Blog.

Note

This article is obsolete; there is an intrinsic function, named CallerNode, to capture this functionality.

../../_images/determine_calling_procedure.png

Determine calling procedure

For something we were working on, we had to find a way to determine which procedure was calling the current procedure.

One very trivial way would be to introduce an additional argument for the procedure in which the calling procedure must provide its name. The main disadvantage of this approach is that each procedure must always provide this additional input argument. Furthermore, it is also not very robust as there is nothing preventing a procedure to provide the name of a different procedure as the input argument instead of its own.

Therefore, we needed another approach that can determine which procedure did the call to the current procedure.

Instead of relying on an additional input argument, we made use of an approach that uses the error handling introduced in AIMMS 3.10. With the functions provided for the error handling, you can obtain the call stack that lead to the current error. So the basic steps for obtaining information about which procedure called the current procedure are:

  1. Raise an error

  2. Use error handling functions to query the call stack of this raised error,

  3. Mark the error as handled so that AIMMS discards it

In AIMMS, this can be done by introducing a new procedure with the code below. Note that CallingProcedure must be an element parameter in the predefined set AllProcedures and that err must be an element parameter in the predefined set errh::PendingErrors.

 1!This element parameter will hold the calling procedure
 2CallingProcedure := '' ;
 3
 4!Within a block statement, raise an error and use a block-local
 5!error handler to query the details of the error
 6block
 7
 8    raise error "Artificial error to detect procedure name" ;
 9
10onerror err do
11
12    ! To get the name of the procedure that actually called
13    ! the current procedure, we must get the second node in the stacktrace.
14    ! This information can be obtained via the errh::Node function
15
16    CallingProcedure := errh::Node( err, 2) ;
17
18    !Now mark the error as handled so that AIMMS will discard it
19    !for further processing
20
21    errh::MarkAsHandled(err,1) ;
22
23    !Ensure that the predefined string parameter CurrentErrorMessage
24    !is emptied.
25
26    CurrentErrorMessage := "";
27
28endblock ;