* Performing I/O on Private Types in Ada 9X (Was Re: OO Preprocessor for Ada)
@ 1993-08-20 17:49 cis.ohio-state.edu!magnus.acs.ohio-state.edu!math.ohio-state.edu!darwin.s
0 siblings, 0 replies; 2+ messages in thread
From: cis.ohio-state.edu!magnus.acs.ohio-state.edu!math.ohio-state.edu!darwin.s @ 1993-08-20 17:49 UTC (permalink / raw)
>Obviously you're right, I was just asleep in the front row again.
>
>I guess what this example triggered was painful memories of trying
>to provide text_io capabilities when you declare a limited private type.
>Does anyone have an elegant example of how to do this with 9X with tagged
>types and text_io generics?
>
>I guess to further define the problem, using this running example,
>how can I provide a text_io print capability of an object of type X.Object?
>(i.e. how do I print An_Object directly?).
Well, by the very nature of An_Object being declared of a private type, you
can't -- and the fact that this private type happens to be tagged doesn't
change that. In other words, an ordinary piece of client code is afforded no
more visibility into a tagged object's private structure than is realized by a
non-tagged object. While an ordinary program unit may indeed extend a tagged
type with new components, the program unit that derives the new type does not
gain visibility into the original type's private part simply by doing such a
type extension. But fear not, for your "painful memories" may be disposed of
by an entirely different feature of Ada 9X, that being the _child library
unit_.
A child library unit is a separately compiled program unit that, among other
things, can "see" into the private structure of its parent package. Such a
construct allows us to effectively add declarations to an existing package
without requiring modification to the original package itself. Much as tagged
types allow us to extend the set of components defined for an existing record
type, child library units allow us to extend the set of declarations defined
by an existing package.
Now although I've used child units to implement inheritance hierarchies, I
haven't yet applied them to I/O problems. But for the sake of addressing this
key problem in Ada 83, I'll give it a shot (Tucker, watch out for me, and jump
in any time...).
To re-establish context, I'll re-specify the example package used in earlier
postings:
package X is -- Represents a class X identified in OOA/OOD
type Object is tagged limited private; -- Represents a "root class"
procedure Create (Instance : in out Object); -- "constructor"
A1 : in Integer);
procedure Modify (Instance : in out Object; -- "modifier"
A1 : in Integer;
function P1 (Instance : Object) return Integer; -- (direct) "selector"
private
type Object is tagged
record
A1 : Integer;
end record;
end X;
(Note that I changed each identifier P1 to A1, suggesting that the components
of the tagged record represent an object's _Attributes, and that direct
selector functions can be simply named accordingly.)
Now, consider the following child library unit created from the parent package
X shown above:
package X.IO is
procedure Print_Attributes (Instance : in Object);
-- the type Object is directly visible from the parent unit X
end X.IO;
-----------------------------------------------------
with Text_IO;
package body X.IO is
procedure Print_Attributes (Instance : in Object) is
-- Could instantiate Text_IO.Integer_IO instead of using 'IMAGE below
begin
Text_IO.Put ("The value of A1 is ");
Text_IO.Put ( Integer'IMAGE(Instance.A1) ); -- A1 directly visible
-- Could print other attributes if they existed
end Print_Attributes;
end X.IO;
Note that the child unit is afforded _direct_ visibility to all of its
parent's specifications. This is why the formal parameter for
Print_Attributes need not reference the type as X.Object. But to really
address Ken's questions on I/O, the child's _body_ has direct visibility to
its parent's _private_ declarations as well. For those readers familiar with
C++, child library units provide the "protected" form of visibility control
defined by classes, which gives derived classes direct visibility into their
parents' otherwise hidden members. Note, however, that in C++, the class
designer must decide which members are to be "protected," whereas in Ada 9X,
the "subclass" designer makes the decision.
This is, I think, a most significant enhancement to Ada 83's sometimes overly
restrictive visibility rules regarding packages with private parts. But maybe
what's even more notable about using child library units in this way is that
the original (parent) package X need not ever be concerned with the often
unstable and non-portable nature of performing I/O in general. Thus, package
designers can now readily build software components independently of any I/O
that might be needed, knowing that such capabilities can be later developed
and modified totally separately.
For completeness, I'll revise the client code specified earlier, having it
call upon the I/O child package to do its printing instead of within the
client itself:
with X.IO; -- Implicitly with's in X as well
procedure Some_Client_With_IO_Removed is
An_Object : X.Object;
begin
X.Create (Instance => An_Object, A1 => 7);
X.Modify (An_Object, A1 => 3);
X.IO.Print_Attributes (Instance => An_Object);
end Some_Client_With_IO_Removed;
Note that references to lower-level child units can become quite lengthy. In
these cases, proper application of renaming (or the 'use' statement) would be
in order. In any event, I think that this new capability of Ada 9X is most
remarkable, especially for those like Ken Rowe who have been previously
frustrated with Ada 83's "all-or-nothing" effect of private types.
--
Gary J. Cernosek
Fastrak Training Inc.
Houston Office: (713) 280-4768
E-mail: cernosek@source.asset.com
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: Performing I/O on Private Types in Ada 9X (Was Re: OO Preprocessor for Ada)
@ 1993-08-23 16:03 cis.ohio-state.edu!pacific.mps.ohio-state.edu!math.ohio-state.edu!howland
0 siblings, 0 replies; 2+ messages in thread
From: cis.ohio-state.edu!pacific.mps.ohio-state.edu!math.ohio-state.edu!howland @ 1993-08-23 16:03 UTC (permalink / raw)
I like your example, but let me do a more concrete one.
Let's say I want to provide the capabilities of enumeration io for
my private type. If type Object is not limited private, then
procedure Some_Client_With_Io_Removed can just instantiate enumeration_io:
with X;
with Text_Io;
procedure Some_Client_With_Io_Removed is
package X_Io is new
Text_Io.Enumeration_Io( Enum=> X.Object,
Image=> X.Object'Image,
Value=> X.Object'Value);
...
end Some_Client_With_Io_Removed;
But since X.Object is (tagged) limited private it is not so straight forward.
Using your example I need to do the following:
with Text_Io;
package X.Io is
procedure Get(File: in Text_Io.In_File;Item: out Object);
procedure Get(Item: out Object);
procedure Put(File: in Text_Io.Out_File; Item: in Object;
Width: in Integer := 0;
Lower_Case: in Boolean := False);
procedure Put(Item: in Object;
Width: in Integer := 0;
Lower_Case: in Boolean := False);
end X.Io;
with Text_Io;
package body X.Io is
package Object_Io is new
Text_Io.Enumeration_Io( Enum=> X.Object,
Image=> X.Object'Image,
Value=> X.Object'Value);
procedure Get(File: in Text_Io.In_File;Item: out Object) is
begin
Object_Io.Get(File;Item);
end Get;
procedure Get(Item: out Object) is
begin
Object_Io.Get(Item);
end Get;
procedure Put(File: in Text_Io.Out_File; Item: in Object;
Width: in Integer := 0;
Lower_Case: in Boolean := False) is
begin
Object_Io.Put(File; Item; Width; Lower_Case);
end Put;
procedure Put(Item: in Object;
Width: in Integer := 0;
Lower_Case: in Boolean := False) is
begin
Object_Io.Put(Item; Width; Lower_Case);
end Put;
end X.Io;
-------------------------------
What I'd really like to be able to do is
with Text_Io;
package X.Io is new
Text_Io.Enumeration_Io( Enum=> Object,
Image=> Object'Image,
Value=> Object'Value);
end X.Io;
------
(1) Could I have used renames in the long example?
(2) Is the "really like to" example legal in 9X? (my feeling is that
it isn't).
Ken.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~1993-08-23 16:03 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1993-08-23 16:03 Performing I/O on Private Types in Ada 9X (Was Re: OO Preprocessor for Ada) cis.ohio-state.edu!pacific.mps.ohio-state.edu!math.ohio-state.edu!howland
-- strict thread matches above, loose matches on Subject: below --
1993-08-20 17:49 cis.ohio-state.edu!magnus.acs.ohio-state.edu!math.ohio-state.edu!darwin.s
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox