From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.5-pre1 (2020-06-20) on ip-172-31-74-118.ec2.internal X-Spam-Level: X-Spam-Status: No, score=-1.9 required=3.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.5-pre1 Date: 14 Apr 92 22:53:48 GMT From: eachus@mitre-bedford.arpa (Robert I. Eachus) Subject: Re: associate functions to objects Message-ID: List-Id: Julian Insan Kamil (consp10@bingsunb.cc.binghamton.edu)says: > I'm working on a project for a Software Engineering class, and > we're using Ada to develop a simple database management > application. My part is on building the user interface for the app. > One of the data type that we're using is called an EntryBoard which > is supposed to manage a list of other objects like Fields, Buttons, > Titles, etc. Each of those objects should be attached to a function > that will be called whenever that object is selected (sort of like > callback functions). Now, how do you attach functions to objects? I > consulted my Ada references and it seems that Ada doesn't allow > passing functions as a parameter to a procedure (the way I did it > in C++ to implement the same behavior). I need hints and advice and > examples on how to do this kind of things. Will anybody help me > with some light? Three answers, one simple, one more complex, and one which is just hard work... The "canonical" way to do this in Ada is to make the objects instances of a task type. Task objects and/or objects containing tasks can be passed as parameters, and calls made to entries of these tasks. Problem is that with most current Ada implementations, this is SLOW. The "clever" way to do this, which works on all Ada compilers which I've tried it on is to pass addresses as parameters and use them in address clauses for procedures: procedure App(X: Something; Callback: System.Address) is function Local_Callback return Status; pragma INTERFACE(Ada, Callback); for Local_Callback'Address use Callback; begin if Local_Callback = Busy then.... The language to use in the pragma INTERFACE varies from implementation to implementation, and if the parameter and result profile of the function whose address is passed doesn't match the local declaration, expect fireworks at run-time. But otherwise this is an implementation dependant but fairly standard way of doing callbacks. (The pragma INTERFACE has to be there for legality reasons, since no body is provided for Local_Callback. The address in the address clause need not be static, and in this case it probably will change from call to call.) The third approach is to use generics. Define your object types as generic packages. Each object is then an instance one of these packages. (However, the interaction of abstract types can lead to a LOT of generic formal parameters. See my previous message.) The callbacks can then be passed as generic actual subprogram parameters. It is hard to learn this style of programming but it is very powerful. It can be mixed with abstract types as tasks when some objects need a separate thread of control, and so forth. So choose whichever approach is right for this application. Good luck. -- Robert I. Eachus with STANDARD_DISCLAIMER; use STANDARD_DISCLAIMER; function MESSAGE (TEXT: in CLEVER_IDEAS) return BETTER_IDEAS is...