Determine the calling procedure¶
This article was originally posted to the AIMMS Tech Blog.
This article is obsolete; there is an intrinsic function, named CallerNode, to capture this functionality.
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:
- Raise an error
- Use error handling functions to query the call stack of this raised error,
- 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
AllProcedures and that
err must be an element parameter
in the predefined set
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
!This element parameter will hold the calling procedure CallingProcedure := '' ; !Within a block statement, raise an error and use a block-local !error handler to query the details of the error block raise error "Artificial error to detect procedure name" ; onerror err do ! To get the name of the procedure that actually called ! the current procedure, we must get the second node in the stacktrace. ! This information can be obtained via the errh::Node function CallingProcedure := errh::Node( err, 2) ; !Now mark the error as handled so that AIMMS will discard it !for further processing errh::MarkAsHandled(err,1) ; !Ensure that the predefined string parameter CurrentErrorMessage !is emptied. CurrentErrorMessage := ""; endblock ;
Last Updated: July, 2020