From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII Path: g2news1.google.com!postnews.google.com!e4g2000prn.googlegroups.com!not-for-mail From: Adam Beneschan Newsgroups: comp.lang.ada Subject: Re: Operation can be dispatching in only one type Date: Mon, 16 Nov 2009 09:43:06 -0800 (PST) Organization: http://groups.google.com Message-ID: <94e76749-c49c-45aa-b7dc-386da0d71c66@e4g2000prn.googlegroups.com> References: <025105f2-5571-400e-a66f-ef1c3dc9ef32@g27g2000yqn.googlegroups.com> NNTP-Posting-Host: 66.126.103.122 Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-Trace: posting.google.com 1258393387 8406 127.0.0.1 (16 Nov 2009 17:43:07 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: Mon, 16 Nov 2009 17:43:07 +0000 (UTC) Complaints-To: groups-abuse@google.com Injection-Info: e4g2000prn.googlegroups.com; posting-host=66.126.103.122; posting-account=duW0ogkAAABjRdnxgLGXDfna0Gc6XqmQ User-Agent: G2/1.0 X-HTTP-UserAgent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; WOW64; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.5.21022; .NET CLR 3.5.30729; .NET CLR 3.0.30618),gzip(gfe),gzip(gfe) Xref: g2news1.google.com comp.lang.ada:8115 Date: 2009-11-16T09:43:06-08:00 List-Id: On Nov 13, 12:12=A0pm, xorque wrote: > Hello. > > I'm trying to write an archive/directory abstraction in a similar vein > to PhysicsFS > but am at a bit of a loss as to how to design the archiver interface: > > with Path; > > package Archiver is > > =A0 type Archiver_t =A0 =A0 =A0 =A0 =A0 =A0 =A0is abstract tagged limited= private; > =A0 type Archiver_Class_Access_t is access Archiver_t'Class; > > =A0 procedure Init > =A0 =A0 (Archiver : out Archiver_t) is abstract; > > =A0 function Can_Mount > =A0 =A0 (Archiver : in Archiver_t; > =A0 =A0 =A0Path =A0 =A0 : in Path.Real_t) return Boolean is abstract; > > =A0 type File_t =A0 =A0 =A0 =A0 =A0 =A0 =A0is abstract tagged limited pri= vate; > =A0 type File_Class_Access_t is access File_t'Class; > > =A0 procedure Open > =A0 =A0 (Archiver : in =A0 =A0 Archiver_t; > =A0 =A0 =A0Path =A0 =A0 : in =A0 =A0 Path.Virtual_t; > =A0 =A0 =A0File =A0 =A0 : =A0 =A0out File_t) is abstract; > > =A0 procedure Close > =A0 =A0 (File : in out File_t) is abstract; > > private > > =A0 type Archiver_t is abstract tagged limited null record; > > =A0 type File_t is abstract tagged limited null record; > > end Archiver; > > The idea of the above is that the main part of the library only deals > with > archivers and "files" (which might only really be pointers to entries > in Zip > files, for example) by 'Class. > > The problem with the above is that: > > archiver.ads:18:13: operation can be dispatching in only one type > > Hopefully someone here knows a better way to handle this. I don't know what PhysicsFS is, so I'm not clear on what you are trying to accomplish. Maybe your plan is to define concrete types derived from Archive_T and File_T that go together, in pairs. For example, a programmer might define one package Archive_1 that defines Archive_1_T and File_1_T, and another user might write a package Archive_2 that defines Archive_2_T and File_2_T, but the intent is that the two would be dependent---i.e. you would always use Open with two objects that go together, such as an object of type Archive_1_T with a File_1_T, or an Archive_2_T with a File_2_T, but never with an Archive_1_T and a File_2_T. In that case, you would make one parameter classwide, as Dmitry suggested: procedure Open (Archiver : Archiver_t'Class; -- Class-wide Path : Virtual_t; File : in out File_t) is abstract; Then an implementation would need to check manually to make sure the type is correct: procedure Open (Archive : Archiver_T'Class; Path : Virtual_T; File : in out File_1_T) is begin if Archive not in Archive_1_T then raise with "Open on File_1_T used with wrong archiver class"; end if; declare The_Arch : Archive_1_T renames Archive_1_T(Archive); begin ... ... and now you have an Archive_1_T and a File_1_T to work with. (I haven't checked this to make sure it's correct. But it would be something like this.) By the way, for a while I was considering requesting a language change to allow this sort of restricted multiple dispatch, in cases where a primitive operation of two types could be declared and inherited for two derived types that are derived in the same package, and when dispatching, the program would check to make sure the two actual types really were declared in the same package. This would avoid having to deal with M x N combinations of types---something that I think is an issue with MI---since it only deals with pairs (or triplets, etc.) of types that are defined to "go together". I could try to write a proposal if there's enough interest, but I think it's too late to get into the next language revision. If your plan is that Archiver and File types be more independent, though, what you may need to do is to pick one of the parameters to Open, say Archive (as above) to be a class-wide type, and then provide enough operations on Archiver_T so that an implementation of Open could dispatch on Archive to do whatever needs to be done with the archive. If you have some other idea about the relationship between Archiver and File, then you might need to give me more specifics about how you intend your package to be used. -- Adam