From: Adam Beneschan <adam@irvine.com>
Subject: Re: Learning tagged types
Date: Fri, 22 Feb 2008 16:04:11 -0800 (PST)
Date: 2008-02-22T16:04:11-08:00 [thread overview]
Message-ID: <e6edf9a6-9172-4121-bfd8-bda0ba16d6ab@h11g2000prf.googlegroups.com> (raw)
In-Reply-To: 31ec7e11-3cd0-4f3c-ad11-c06e7edfb9cb@e10g2000prf.googlegroups.com
On Feb 22, 3:23 pm, mhamel...@yahoo.com wrote:
> Hello, this is a representative bit of code I use and, experimenting
> with tagged types, want to know if/how this can be cleanly moved to a
> more object oriented format. I think I want proc and def to be
> abstract procedures, that requires the "object" Proc_Def itself to be
> abstract, that means declaring new packages everytime I have a new
> Proc_Def? Thanks for any pointers (no pun intended),
>
> with Text_Io;
> with Ada.Containers.Doubly_Linked_Lists;
>
> procedure Tag_Test2 is
>
> type Proc_Def;
>
> type Proc_Ptr is access procedure (Def : Proc_Def;
> Val : Float);
> type Term_Ptr is access procedure (Def : Proc_Def);
>
> type Proc_Def is
> record
> Name : String (1 .. 4);
> Proc : Proc_Ptr;
> Term : Term_Ptr;
> end record;
I think what you want is to declare a root type instead of Proc_Def.
I don't know what you really want to call it, but you probably want to
make it an abstract type; then, instead of Proc_Ptr and Term_Ptr,
you'd declare "Proc" and "Term" or something like that to be primitive
operations of the root type. E.g.
type Root is abstract tagged
record
Name : String (1 .. 4);
end record;
procedure Proc (Def : Root; Val : Float) is abstract;
procedure Term (Def : Root) is abstract;
You do need to declare Root in a package specification, and Proc and
Term in the same specification. (But the package could be nested
inside a procedure, if you really want it to.)
Then whenever you want to declare a particular version of this with
its own versions of Proc and Term (such as your Proc1 and Term1
below), you'd declare a type extension:
type Some_Type is new Root with null record;
overriding procedure Proc (Def : Some_Type; Val : Float);
overriding procedure Term (Def : Some_Type);
("overriding" is an Ada 2005 extension; it's not required, but is
there to help protect against accidents. In Ada 95, just leave that
word off.)
A caveat: In Ada 95, Some_Type can't be declared inside a procedure
unless Root was declared earlier inside that same procedure. In Ada
2005, this restriction is relaxed, but I still think you'll have to
follow it if you use it with Doubly_Linked_Lists---otherwise you could
create a list that points to a Some_Type object after Some_Type is no
longer visible.
Of course, Some_Type doesn't have to say "with null record". If you
like, you can add additional fields---in fact, one of the purposes of
a more object-oriented style would be so that you can have additional
data for Some_Type that is just for that type and not for every type
in the class.
Now, instead of Proc_Def in the following declarations, you'd use
Root'Class since the type could be any type in the class:
> package DLL is new Ada.Containers.Doubly_Linked_Lists (Proc_Def);
> Proc_List : DLL.List;
>
> procedure Insert_Proc (Def : Proc_Def) is
> begin
> Proc_List.Append (Def);
> end Insert_Proc;
>
> function Retrieve_Proc return Proc_Def is
> begin
> return Proc_List.First_Element;
> end Retrieve_Proc;
The following would be the overriding bodies of Proc and Term for your
Some_Type type:
> procedure Proc1 (Def : Proc_Def; -- change this to Some_Type
> Val : Float) is
> begin
> Text_Io.Put_Line (Def.Name & ": processing - " & Val'Img);
> end Proc1;
>
> procedure Term1 (Def : Proc_Def) is -- change this to Some_Type
> begin
> Text_Io.Put_Line (Def.Name & ": shutting down");
> end Term1;
>
> Test_Proc : Proc_Def;
>
> begin
> Insert_Proc (("test", Proc1'access, Term1'access));
The above would become Insert_Proc (Some_Type' (Name => "test")).
> Test_Proc := Retrieve_Proc;
> Test_Proc.Proc (Test_Proc, 5.0);
> Test_Proc.Term (Test_Proc);
> end Tag_Test2;
To answer your other question: no, you don't have to declare a new
package for every new type in the class. Some programmers like doing
that, but that's a matter of style.
I haven't actually tried this. You may have to fill in some of the
details, and I could have gotten one or two things wrong. But
hopefully this will at least get you started.
-- Adam
next prev parent reply other threads:[~2008-02-23 0:04 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-02-22 23:23 Learning tagged types mhamel_98
2008-02-23 0:04 ` Adam Beneschan [this message]
2008-02-25 19:48 ` mhamel_98
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox