A question for the OOABL experts out there...
I have some OOABL code that has been updated so that method output parameters returning handles for temp-table, datasets etc. have been changed to use return values on the methods instead.
METHOD PUBLIC VOID rtbGetWorkspace( INPUT pcWorkspaceId AS CHARACTER, OUTPUT TABLE-HANDLE phTT ): RUN rtb/proxy/p/rtbGetWorkspace.p ON AppServerHandle ( INPUT pcWorkspaceId, OUTPUT TABLE-HANDLE phTT). RETURN.
FINALLY: DELETE OBJECT phTT NO-ERROR. END FINALLY.
Has been changed to:
METHOD PUBLIC HANDLE rtbGetWorkspace( INPUT pcWorkspaceId AS CHARACTER): DEFINE VARIABLE hTT AS HANDLE NO-UNDO. RUN rtb/proxy/p/rtbGetWorkspace.p ON AppServerHandle ( INPUT pcWorkspaceId, OUTPUT TABLE-HANDLE hTT). RETURN hTT.
Initially, I had the DELETE OBJECT code in the FINALLY of the updated method. But this resulted in the code not working any more, as the returned hTT handle was then ?.
Is it correct that it is not longer necessary to delete handles explicitly to avoid memory leaks in use cases like this?
Regards / Med Venlig Hilsen
Thomas Hansen Director ___________________________________ appSolutions a|s
> Is it correct that it is not longer necessary to delete handles explicitly to avoid memory leaks in use cases like this?
METHOD PUBLIC VOID rtbGetWorkspace( INPUT pcWorkspaceId AS CHARACTER, OUTPUT TABLE-HANDLE phTT ):RUN rtb/proxy/p/rtbGetWorkspace.p ON AppServerHandle (INPUT pcWorkspaceId,OUTPUT TABLE-HANDLE phTT).RETURN.
FINALLY: DELETE OBJECT phTT NO-ERROR.END FINALLY.
METHOD PUBLIC HANDLE rtbGetWorkspace( INPUT pcWorkspaceId AS CHARACTER):DEFINE VARIABLE hTT AS HANDLE NO-UNDO.RUN rtb/proxy/p/rtbGetWorkspace.p ON AppServerHandle (INPUT pcWorkspaceId,OUTPUT TABLE-HANDLE hTT).RETURN hTT.
Flag this post as spam/abuse.
I would suggest that the fundamental issue here is violating encapsulation by returning a handle in the first place. Quite aside from the nicities of OO, that is bound to make it ambiguous where you should clean up those references. Instead, bundle all of the functionality for manipulating the TT or DS within the object and return ordinary values in response to methods. Much cleaner.
Consulting in Model-Based Development, Transformation, and Object-Oriented Best Practice http://www.cintegrity.com
I am waiting for an actual use case. I can imagine circumstances where one would want to return an object which encapsulated a TT, but no use cases yet where there is a need for two objects to share a TT definition.
Maybe you should start a seperate thread for that discussion?
The OP’s question has already been answered. So why start the same old endless never agreed religious debate over again?
Architect of the SmartComponent Library and WinKit
Thanks Peter - the procedures and classes using this wrapper class are cleaning up. So there should not be a problem there.
FYI - The code is constructed as it is right now because it was created as a an OOABL wrapper for a bunch of procedure based proxies that return temp-tables with data. So it may not be best practice - but it works ;-)
Mike, the reason for bringing it up is because sometimes the right answer to a question is that one shouldn't be trying to do the thing one is asking about. Circumstances like Thomas' may cause one to violate good principles, but one shouldn't do it casually or, more importantly, without knowing what one is doing.
But aren’t there enough discussion of that kind on this forum for those looking for that advice?
“but no use cases yet where there is a need for two objects to share a TT definition.”
Did you actually look at the source from the original post? The class with the method returning the temp-table’s handle does not keep knowledge about the temp-table.
So from my point of view, there is no shared temp-table anywhere and anytime. It’s more like a factory returning an object to the caller.
Then why not wrap it and remove the ambiguity. A factory is exactly the kind of case I was referring to. Now, to be sure, in Thomas' case he is trying to interface with legacy code so at some point one has to decide what interface is acceptable and, in the short run, that can mean defining interfaces which one wouldn't otherwise use. Thomas' original question is indicative of the ambiguity of the situation.
Not knowing whether he should be deleting the object in this object, where he had been or deleting it somewhere else isn't indication of ambiguity? Non-ambiguous would be having it be immediately clear where the delete should happen.
And hiding the temp-table type object in a Progress.Lang.Object inheriting object does change this exactly why? Because you feel smarter because you put a class around
Just because one object is handle based and the other is PLO derived does not change anything on the question who should be deleting that thing. His question then
would be, where should my object be deleted. Is that of a different quality? Certainly not. A temp-table is an object. You can return references, you can return a copy, you can keep the reference when returning or not.
Since I wrote the called code, I will comment. :)
The code is not "legacy code"; it is the server API layer for our plug-in client.
The procedure is this particular layer is returning a TABLE-HANDLE (not an HANDLE) and cannot return an encapsulated ABL object because it is coming across the appserver whose principal receiver is a java client. The TABLE-HANDLE parameter translates into a resultSet when invoked via java via the proxy-generated classes.
So as one can see, it's not always black and white. Sometimes you gotta build for the gray areas as well.
Anyhow, yes Thomas you should always do a DELETE OBJECT for TABLE-HANDLE parameters.
Jeff Ledbetter Product Architect | Roundtable Software
Unlike a PLO object, aka a real object since a TT or DS has a ways to go before one can really treat it like an object, the real object does not need to have its definition every place it is used. Unlike a TT, one can bury all the access logic in the real object so that the outside world sees only the methods and properties of the object. And, unlike a TT defined in multiple compile units, it is usually quite clear who should delete a real object .... either based on the you made it, you delete it rule or because the object is passed to a consumer and the consumer defines the end of life.