[fpc-pascal] Question about interfaces and patch
Michael Van Canneyt
michael.vancanneyt at wisa.be
Thu Mar 24 15:01:47 CET 2005
On Thu, 24 Mar 2005, ml wrote:
> On Thu, 2005-03-24 at 09:06 +0100, Michael Van Canneyt wrote:
>> On Thu, 24 Mar 2005 ml at brainwashers.org wrote:
>>> Quoting Michael Van Canneyt <michael.vancanneyt at wisa.be>:
>>>> On Wed, 23 Mar 2005 ml at brainwashers.org wrote:
>>>>> Quoting Marco van de Voort <marcov at stack.nl>:
>>>>>>> On Tue, 22 Mar 2005, ml wrote:
>>>>>>>> // than one interface
>>>>>>>> a := (object as IA); // correct
>>>>>>>> b := (object as IB); // returns pointer to the first interface
>>>>>>>> c := (object as IC); // returns pointer to the first interface
>>>>>>>> // there's no way to do again it's like direct call to exception
>>>>>>>> obj := a; // returns pointer(obj) + 12 ???
>>>>>>> This is nonsense. You cannot assign an interface to a class.
>>>>>>> A class IMPLEMENTS an interface, it is not an interface.
>>>>> Ok, its nonsense. I said it already works with my patch, but I guess you
>>>>> know it better. So my example down there doesn't work (with patch). You
>>>>> should know.
>>>>> I (; can't ;) transfer from one interface to other back to object and to
>>>>> 3rd interface. I just imagine my results.
>>>> Tell me, what is
>>>> obj := a;
>>>> supposed to DO ? A class has a set of methods. Some of these methods form
>>>> the VMT of an interface. What your code does, is say
>>>> "don't use your VMT methods, use these instead' ?
>>> Yes, exactly. I even provided test example at the bottom of my previous message,
>>> where I transfered from class to IA, back to class and then to ID. And called
>>> ID.D; And it just works (this is also nice start for blind properties
>>> implementation, which now also became possible, since original vmt is now visible)
>>> But, It should be used as
>>> if (TObject(a).InheritedFrom(TSomeClass)) then begin
>>> obj := TSomeClass(a); // note that here obj is declared as TSomeClass
>>> // now safely use as this vmt
>>> if SupportsInterface(TObject(a), IB) then begin
>>> ibvar := a; // declared ibvar: IB
>>> // now safely use as this vmt
>>> in perfect world "is" would return InheritedFrom or SupportsInterface result and
>>> not actual class check, if true then all needed operations are satisfied.
>> I can understand that 'is' should be able to check interfaces; this is a
>> useful patch.
>> I also understand what your code should do.
>> BUT I see some flaws in your design.
>> IA = Interface
>> procedure InitF;
>> TA = class(TObject,IA)
>> F : TList;
>> Procedure InitF;
>> Procedure B;
>> Procedure TA.InitF;
>> Procedure TA.B;
>> A : TA;
>> C : IA;
> Completely wrong type of thinking here, and I can't answer you what you
> asked, so I provided answer why I can't answer and how it should be used
>> C:=SomeIA; // Get an IA interface from somewhere.
> Why would someone create one object just to override its variable with
> some other value? To create memory leaks?
was supposed to be the equivalent of YOUR code :
// there's no way to do again it's like direct call to exception
obj := a; // returns pointer(obj) + 12 ???
> Here we go again. Your main problem is that you don't understand (or you
> lack imagination) what interface is in his complete feature set. Main
> feature of interfaces is to have ability to predict combinations of
> commands that interfaces support, as I already specified... having
> monolithic interface structure makes no sense (you just get mirror copy
> of classes), it's a waste of time, paper and space. And before you
> answer how it is not possible, or how you don't have time to implement
I was not going to answer any of this, I'm trying to understand what you
want to accomplish, and why this could be useful for other people.
> I'm game. I'm prepared to make all the necessary changes and
> patches. All that I would ask for is a few pointers (if that could be
> done on line on some irc or msn channel, that would be perfect, it's
> hard to talk in one e-mail a day) how and where so that I don't need to
> dissect complete compiler code (you probably understand that I'm not as
> familiar with its code as you are, that would be only few questions like
> "where does it...", "how does it...", "what would be the preffered
> implementation of ...").
> Here is a simple example how it should be used
> IReportable = interface
> function Report: string;
> // let's say that this should write report and
> // return status description as string
> ILogged = interface
> procedure Log(aStr: string);
> And now some completely different place in your software, main feature
> of interfaces is that you can predict possible features, and not even
> start to implement them at that moment
> procedure MyXYZPart.DoReport(aRep: IReportable);
> if (aRep <> nil) then begin
> if (aRep is ILogged) then
> (aRep as ILogged).Log(aRep.Report)
I see what you want, but if you would do
procedure MyXYZPart.DoReport(aRep: TInterfacedObject);
if (aRep <> nil) and arep is IReportable then begin
if (aRep is ILogged) then
(aRep as ILogged).Log(aRep.Report)
you would have the same effect ?
Necessarily, there is always SOME instance implementing any interface...
> Meaning, that if I derived some class as (and call DoReport with it as
> TSomeClass = interface(TInterfacedObject, IReportable, ILogged)
> this class will have to contain all the logging facility needed, and
> that's conditioned with interfaces (otherwise it won't be compiled).
> TSomeClass2 = interface(TInterfacedObject, IReportable)
> this class will automatically skip logging, because logging interface is
> not supported by class
> What is difference here? I could pass a simple interfaced object as
> parameter and predict possibility of logging. If object or interface
> support that option then all the facility needed is supported and
> logging is done.
> This is how and why interfaces should be used, for predicting features.
> And with interfaces as they are this is just impossible.
But with a slight change in your code, I think it is, see above ?
If I understand you correct, you want to query the instance 'behind'
some interface to see if it inmplements another interface, without
having to access the actual instance ?
This still does not explain why you would need to do
AClassInstance := AnInterface;
( your own obj:=a; statement )
Which seems to me against all pascal rules of strict typing ?
More information about the fpc-pascal