From: eachus@spectre.mitre.org (Robert I. Eachus)
Subject: Re: How to Use Abstract Data Types
Date: 1998/04/30
Date: 1998-04-30T00:00:00+00:00 [thread overview]
Message-ID: <EACHUS.98Apr30161723@spectre.mitre.org> (raw)
In-Reply-To: 6hm556$95u$1@nnrp1.dejanews.com
In article <6hm556$95u$1@nnrp1.dejanews.com> adam@irvine.com writes:
> But it looks like this isn't going to work. If I were to write a
> procedure that lists all the books in a library whose titles match,
> I'd want to be able to write:
> procedure List_Books_With_Matching_Titles
> (Lib : in Library'Class;
> Title_Pattern : in String) is
> ... declarations
> begin
> Scan_By_Title (Lib, Title_Pattern, List_Scan, Error);
> if Error then
> Insult_The_User;
> return;
> end if;
> while More_Books (List_Scan) loop
> Next_Book (List_Scan, The_Book_To_List);
> List_Book (The_Book_To_List);
> end loop;
> Close_Scan (List_Scan);
> end List_Books_With_Matching_Titles;
> But I don't see how this can be done, since I can't declare List_Scan.
> I can't declare it as Library_Package.Scan_Info since that is an
> abstract type...
-- Actually you can have non-abstract operations of abstract types,
-- but there is a better solution here.
> Am I missing something trivial here?
-- Yes, but you can be forgiven because it is not trivial in many OO
-- langauges. There are cases where you have to use access parameters
-- and all that to duplicate the normal way of doing iterators in
-- other languages. In Ada, you are always better off making
-- iterators objects, but in Ada 95 the much cleaner way of doing
-- iterators is to use instances of generic packages as the iterator
-- objects. Sounds compilicated, but it isn't. First, we will
-- realize that Books and libraries are separate abstractions:
package Books is
type Book is ...;
function Title(B: Book) return String;
...
end Books;
with Books
package Libraries is
type Library is abstract tagged null record;
-- various abstract operations on Libraries.
generic
type Some_Library is new Library with private;
This_Library: in out Some_Library;
package Iterator is
function More return Boolean;
function Next return Book'Class;
end Iterator;
private
...
end Libraries;
The body of Iterator will call (abstract) primitives on Libraries.
Of course, when Iterator is instantiated, it will be on a non-abstract
class, so there will be actual code to call. But that is not your
worry.
> What is the cleanest way to accomplish what I'm trying to do? This
> looks like such a typical use of polymorphism that I'd be surprised if
> there were no intuitive way to do it.
Now to write your Scan_by_Title, lets make it a child of Libraries:
generic
type Some_Library is new Library with private;
procedure Libraries.Scan_By_Title (Lib : in Some_Library;
Reg_Expression : in String;
Scan : out Scan_Info;
RE_Error : out Boolean);
procedure Libraries.Scan_By_Title (Lib : in Some_Library;
Reg_Expression : in String;
Scan : out Scan_Info;
RE_Error : out Boolean) is
...
package Local_Iterator is new Libraries.Iterator(Some_Library, Lib);
begin
...
while Local_Iterator.More loop
Process_Book(Local_Iterator.Next, {other parameters});
end loop;
end Libraries.Scan_By_Title;
I made this a child of Libraries for exposition purposes, you may
want to have Scan_By_Title as an abstract primitive of the Library
type and in effect, require that all non-abstract types derived from
Library provide a body, or you could make it a non-abstract primitive.
My leaning is to provide the Iterator as a child of Libraries, but to
provide the search function as an abstract primitive. In other words,
some Library implementations may not have a concept of an ordering
among books, but might still provide a search mechanism.
--
Robert I. Eachus
with Standard_Disclaimer;
use Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...
next prev parent reply other threads:[~1998-04-30 0:00 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
1998-04-22 0:00 How to Use Abstract Data Types adam
1998-04-23 0:00 ` Jacob Sparre Andersen
1998-04-30 0:00 ` Robert I. Eachus [this message]
[not found] ` <matthew_heaney-ya023680003004981709380001@news.ni.net>
1998-05-05 0:00 ` Stephen Leake
1998-05-05 0:00 ` Matthew Heaney
1998-05-06 0:00 ` Stephen Leake
-- strict thread matches above, loose matches on Subject: below --
1998-04-30 0:00 adam
1998-05-06 0:00 ` Robert I. Eachus
1998-05-04 0:00 adam
1998-05-06 0:00 ` Robert I. Eachus
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox