comp.lang.ada
 help / color / mirror / Atom feed
From: adam@irvine.com
Subject: Re: Active Iteration (was: How to use abstract data types)
Date: 1998/05/08
Date: 1998-05-08T00:00:00+00:00	[thread overview]
Message-ID: <6ivjdn$k0m$1@nnrp1.dejanews.com> (raw)


Matthew, thanks for all the information---this really does help me see
what's going on.

> Use static binding when you need static binding, and use dynamic binding
> when you need dynamic binding.  Don't think that importing a formal derived
> type is somehow "superior" to the traditional way.  It's its complement,
> not replacement.

FWIW, I believe I do need dynamic binding in the tool I'm working on.
Of course, I'm not actually working on a program to list book titles,
but I am working on a program that will have to deal with some
radically different types of files, and the program will either use a
command-line option or take a peek at a file's header to figure out
what kind of file it's dealing with.  Sorry that I didn't make that
clear when I came up with my "Libraries" example; I didn't see at the
time that it was necessary to mention this.

So if, say, the program asks the user to select a type of library from
a menu, and then contains code like

      if Menu_Option = 1 then
          declare
              Lib : aliased Libraries.Test.Library :=
                        Libraries.Test.The_Library;
          begin
              Let_The_User_Play_With_The_Library (Lib'access);
          end;
      elsif Menu_Option = 2 then
          declare
              Lib : aliased Libraries.Another_Test.Library :=
                        Libraries.Another_Test.The_Library;
          begin
              Let_The_User_Play_With_The_Library (Lib'access);
          end;
      elsif Menu_Option = 3 then
          declare
              Lib : aliased Libraries.Amazon_Dot_Com.Library :=
                        Libraries.Amazon_Dot_Com.The_Library;
          begin
              .... some stuff to set up an FTP connection ....
              Let_The_User_Play_With_The_Library (Lib'access);
          end;
      . . .

where Let_The_User_Play_With_The_Library's parameter is "access
Root_Library'class", and Let_The_User_Play_With_The_Library somewhere
down the road calls List_Books, it doesn't seem to me that the generic
version you used in your previous example:

    procedure Library_Package.Test.List_Books is
      new Library_Package.List.List_Books
      (Source_Library  => Test_Library'Class,
       Source_Iterator => Test_Iterator);


    with Library_Package.Test.List_Books;
    use Library_Package.Test.List_Books;

    procedure Libtest2 is
        The_Lib : Library_Package.Test.Test_Library;
    begin
        List_Books (The_Lib, "m");
    end Libtest2;

will work.  However, the example code you included in your more recent
example should work fine in a case like this.  Am I understanding
what's going on correctly?


> 4) Constructors are functions in Ada.  That means to create a new iterator
> object on the heap, you don't return it as a procedure out param.  It
> should be a function that returns the type, ie
>
>    function New_Iterator
>      (Lib : access Root_Library) return Iterator_Access is abstract;
>
>    function New_Iterator
>       (Lib : access Test_Library) return Iterator_Access;

In my original post, my procedure declaration looked like this:

    procedure Scan_By_Title (Lib            : in Library;
                             Reg_Expression : in String;
                             Scan           : out Scan_Info;
                             RE_Error       : out Boolean)
        is abstract;

where Scan_Info is the iterator.  This can't be made into a function
because it returns two things.

But I think I see what happened here.  I was assuming that the
function (or procedure) that constructed the iterator was also the one
that set it up for the specific purpose I needed it for.  (Which might
be right in some cases.)  Your example, though, has one function to
create the iterator, and a second procedure (Scan_For_Substring) to
actually start the scan process.

OK, that makes sense.  Actually, that's the kind of thing I was
looking for with my original post.  I presume that New_Iterator could
create the iterator with some sort of "Useless" flag so that if you
tried Get_Book or Is_Done or Advance on the iterator without one of
the other setup routines, the program would get upset.


> This is an example of an indefinate type - Root_Iterator'Class (remember,
> all classwide types are indefinate) - that is also limited.  For an
> indefinate type, I need to give it some initial value, so I need to invoke
> a constructor to do that.  But I can't for limited types.  Major league
> bummer.

Last time I saw a problem similar to this, it was in a little book by
Joseph Heller . . .


> 8) Don't have a primitive operation of a tagged type return a
> specific type, ie
>
>    function The_Library return Root_Library is abstract;

That was my mistake.  I should have had it return Root_Library'Class.

                                -- Adam

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/   Now offering spam-free web-based newsreading




             reply	other threads:[~1998-05-08  0:00 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1998-05-08  0:00 adam [this message]
1998-05-09  0:00 ` Active Iteration (was: How to use abstract data types) Matthew Heaney
1998-05-09  0:00   ` Simon Wright
  -- strict thread matches above, loose matches on Subject: below --
1998-05-13  0:00 adam
1998-05-13  0:00 ` Matthew Heaney
1998-05-05  0:00 Matthew Heaney
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox