Re: [dws-developer] Destructor
Brought to you by:
hhernler,
mackermann
From: Mark <mnm...@co...> - 2004-01-16 19:44:38
|
Andreas Luleich wrote: >> var>> sl: TStringList; >> someObject: TObject; >> begin >> sl := nil; >> someObject := sl; >> >> if someObject is TStringList then >> showMessage('I''m a TStringList'); >> end; >> >> Using D5, the message does not show. >> > > "sl is TStringList" also results to "False". First check of the > "is"-operator is the test "pointer=nil?" (see CPU Window). So I think > there is no need for the nil check. You are, of course, correct. Sorry I missed that. I'll change that later. Thanks. :) >> Hmm. I think this would work better: (haven't tried it... could be wrong) >> >> Info.Result := Info.RegisterExternalObject(TMyStringList.Create, True, >> False); >> > > Yes, this may work. But I (as user) would NEVER understand, why NO > constructor is called, when creating a new object. That's why I am not a > fan of "your" RegisterExternalObject function (Sorry). A similar > question is unanswered in the forum (2003/12/21 "Why doesn't the > constructor get called?"). I do not have a convincing answer ... :( As you noted before, the wrapped TMeth_TStringList_Create overwrites the object. Without having tested it, would it be better to change it this way? procedure TMeth_TStringList_Create.Execute; begin //constructor TStringList.Create; if not Assigned(ExternalObject) then <== added ExternalObject := TStringList.Create; end; I just tested this and it works the way you want it. However, *many* of the dws2\Libraries do not do this test. When I was first working on it I thought that calling the script objects constructor would *always* create the Delphi object instance. Which is not what I wanted. I may be remembering wrong, but I thought there were problems with the way the ExtObject was passed in. I may have been wrong or it may have changed. At any rate you are correct. I will change the code generator to CREATE differently. However, there is still the issue of the existing Libraries and how they create objects. This is the case for Ibx and Db (two that I checked on). My "RegisterExternalObject" got around the issue by not calling the constructor. Maybe that was a bad thing, but when I first started on DWS I was (and still am) very hesitent about making core changes as I don't have the depth of knowledge that you and others have. If we fix the libraries or replace them with new wrappers then it will all be okay. Then we can change the RegisterExternalObject method to call the constructor. This could still cause problems for people who have created their own wrappers where they didn't do the test either. Any other thoughts on this? ========= Now, about the destructors... >> This was intentional. I thought that declaring the destructor was >> wasted memory (extra symbols) because all you need to do is call .Free >> and TObject implements that. Was I wrong to do this? Does *every* >> class need a destructor or is an ancestor declared one okay? > > > I like the idea to reintroduce the Free-Method (copy-paste of Delphi > code ;) ). > If no one of the developers raises an objection ... I can start a try > (hello Matthias?). But for your problem: Sometimes I take quasi-fix > objects as ExternalObjects (the current form, a button, ttable, tgrid, > etc.) Such an object must not freed at destruction of the IScriptObj. So > a general destruction of the ExternalObject in "TObject.Destroy" (DWS) I > will not support. I would introduce a new flag in TScriptObj?! I personally like the garbage collection ability. I've gotten very used to it. ;) You could add a .Free method that didn't do ANYTHING but would keep it compilable. Now, here is an idea that may be totally wrong but here goes... Could you introduce a .Free() method that simply nilled the script object interface reference? This would have a similar effect in most cases. There might be an unexpected behavior in the following script... <SCRIPT> var sl: TStringList = TStringsList.Create; try sl.Add('Thing'); finally sl.Free; end; sl.Clear; </SCRIPT> What I'm not sure of is how the "sl" would be treated. If that variables reference to the object was nilled then it would correctly cause an error. If there was another reference to the interface somehow then the object would stay alive and the "sl.Clear;" would error but the object would still exist? I don't know. Just a thought. The reason I didn't include any Destroy wrappers was that the DWS type "TObject" includes a destructor. So I thought that finding the method name "Destroy" would *always* work and since you never call a (Delphi) TStringList.Destroy method that it made sense to not include the wrapped method. After all, if the wrapped Destroy method DID exist I wouldn't want it to be called! So what do I do about the Destroy? What type of change is needed? I'm still not completely clear on it. :) -Mark E. |