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!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 ;