comp.lang.ada
 help / color / mirror / Atom feed
* Generic in out object parameters
@ 1997-04-16  0:00 petera
  1997-04-17  0:00 ` Stephen Leake
  1997-04-18  0:00 ` Matthew Heaney
  0 siblings, 2 replies; 4+ messages in thread
From: petera @ 1997-04-16  0:00 UTC (permalink / raw)




A generic unit may have an generic object parameter of mode in out.  I understand that this acts as a renaming of the actual parameter supplied when the unit is instantiated.

Can someone give me a good motivating example of why this is useful?

I'm not looking for an example that illustrates the mechanism - I understand that.  I'm looking for a real-world example that illustrates how the mechanism is useful.

Thanks.

PA

--------------------------------------------------------------------
Peter J. Ashenden                         Email:   petera@ece.uc.edu
Visiting Scholar, Dept ECECS              Phone:   +1 513 556 4756
University of Cincinnati                  Fax:     +1 513 556 7326
PO Box 210030                                   
Cincinnati OH 45221-0030, USA

             http://www.cs.adelaide.edu.au/~petera/
                   (includes PGP public key)






^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Generic in out object parameters
  1997-04-16  0:00 Generic in out object parameters petera
@ 1997-04-17  0:00 ` Stephen Leake
  1997-04-19  0:00   ` Robert Dewar
  1997-04-18  0:00 ` Matthew Heaney
  1 sibling, 1 reply; 4+ messages in thread
From: Stephen Leake @ 1997-04-17  0:00 UTC (permalink / raw)



petera@ece.uc.edu wrote:
> 
> A generic unit may have an generic object parameter of mode in out.  I understand that this acts as a renaming of the actual parameter supplied when the unit is instantiated.
> 
> Can someone give me a good motivating example of why this is useful?
> 

Here's a layer I use over Ada.Command_Lines:

--
--  Purpose :
--      Provide generic routines for reading parameters from the command
--      line.
--
--  Design :
--      Each Get_* procedure reads a particular parameter type from
--      Command_Line.Argument(Next_Arg) and then increments Next_Arg by
--      one.  PARAMETER_ERROR is raised for *any* error, after putting
an
--      appropriate message to Standard_Error.
--
with Ada.Strings.Unbounded;
package Command_Line_IO is

   PARAMETER_ERROR : exception;

   generic
      Default_Expecting : in STRING;
      Next_Arg : in out NATURAL; -- index of next argument to read
   procedure Get_String 
	(Item : out Ada.Strings.Unbounded.Unbounded_String;
         Expecting : in String := Default_Expecting);

   generic
      type Discrete_Type is (<>);
      Default_Expecting : in STRING;
      Next_Arg : in out NATURAL; -- index of next argument to read
   procedure Get_Discrete 
	(Item : out Discrete_Type;
         Expecting : in STRING := Default_Expecting);

   generic
      type Float_Type is digits <>;
      Default_Expecting : in STRING;
      Next_Arg : in out NATURAL; -- index of next argument to read
   procedure Get_Float (Item : out Float_Type;
                        Expecting : in STRING := Default_Expecting);

end Command_Line_IO;

Next_Arg is a global for each Get; this makes the final code read
eaiser:


procedure Get_Options is

   Next_Arg : POSITIVE := 1;  -- next argument to process

   procedure Get is new Command_Line_IO.Get_Discrete 
	(Com_Port_ID_Type, "Com port id", Next_Arg);

   procedure Get is new Command_Line_IO.Get_Discrete 
	(Interfaces.C.Unsigned_Long, "address", Next_Arg);

   procedure Get is new Command_Line_IO.Get_String ("String", Next_Arg);

   use type Ada.Strings.Unbounded.Unbounded_String;
begin
   --
   -- Process options.
   --
   loop
      exit when (Ada.Command_Line.Argument_Count < Next_Arg);

      if Ada.Command_Line.Argument (Next_Arg) = "--help" or
         Ada.Command_Line.Argument (Next_Arg) = "-?"
      then
         Put_Usage;
         raise Fatal_Error;

      elsif Ada.Command_Line.Argument (Next_Arg) = "--com_port" or
         Ada.Command_Line.Argument (Next_Arg) = "-p"
      then
         Next_Arg := Next_Arg + 1;
         Get (Com_Port_ID);

      elsif Ada.Command_Line.Argument (Next_Arg) = "--verbose" or
         Ada.Command_Line.Argument (Next_Arg) = "-v"
      then
         Next_Arg := Next_Arg + 1;
         Verbose := True;
      else
         -- should be root file name

         Get (Root_File_Name, "root file name");

      end if;
   end loop;
end Get_Options;


Clearly, I could have passed Next_Arg as a parameter to each procedure
call, rather than to each instantiation. However, it is somewhat clearer
this way that there must be exactly one Next_Arg, shared by all the Get
procedures. Since I did not overload Ada.Command_Line.Argument, I admit
the abstraction is muddy.

I don't think I've used a generic "in out" parameter any where else.
-- 
- Stephe




^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Generic in out object parameters
  1997-04-16  0:00 Generic in out object parameters petera
  1997-04-17  0:00 ` Stephen Leake
@ 1997-04-18  0:00 ` Matthew Heaney
  1 sibling, 0 replies; 4+ messages in thread
From: Matthew Heaney @ 1997-04-18  0:00 UTC (permalink / raw)




In article <Forum.861207636.14373.petera@woodlands>, petera@ece.uc.edu wrote:

>A generic unit may have an generic object parameter of mode in out.  I
understand that this acts as a renaming of the actual parameter supplied
when the unit is instantiated.
>
>Can someone give me a good motivating example of why this is useful?
>
>I'm not looking for an example that illustrates the mechanism - I
understand that.  I'm looking for a real-world example that illustrates how
the mechanism is useful.

Use it when you want to bind to an already-existing (possibly global)
variable.  I wrote a utility to work with an instantiation of
Text_IO.Integer_IO, to augment the behavior of Put:

generic
   type Num is range <>;
   with procedure Put (Item : Num; Width : Field; Base : Number_Base);
   Default_Width : in out Field;
procedure Generic_Put (Item  : Num;
                                           Width : Field := Default_Width);

So the client (me) could use his instantiation of Text_IO.Integer_IO.   I
needed to get at Default_Width, which is a global variable in the spec of
Text_IO.Integer_IO, so I just bound the instantiation to it:

procedure Put is new Generic_Put (T, TIO.Put, TIO.Default_Width);

Of course, with Ada 95 I can just pass in the instantiation of the package
as a generic actual, so I wouldn't need to do as I've shown above.

The idea is that you can bind the package to some global data - usually to
read - because the allocation of that data is outside the control of the
instantiator.

In David Watt's book, Ada: Language and Methodology, he gives the example
of a package that binds to a device control block:

generic
   Control_Block : in out Device_Data;
package VDU is  ...;

In his example, the generic VDU utilities operate on (already-existing)
device data, but independent of any particular device data object.

Honestly, this is a seldom used feature of Ada.  Especially nowadays,
because we can bind objects to other objects via access discriminants,
binding a package to an object seems a bit out of fashion.

Matt

--------------------------------------------------------------------
Matthew Heaney
Software Development Consultant
<mailto:matthew_heaney@acm.org>
(818) 985-1271




^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Generic in out object parameters
  1997-04-17  0:00 ` Stephen Leake
@ 1997-04-19  0:00   ` Robert Dewar
  0 siblings, 0 replies; 4+ messages in thread
From: Robert Dewar @ 1997-04-19  0:00 UTC (permalink / raw)



Stephen says

<<   generic
      Default_Expecting : in STRING;
      Next_Arg : in out NATURAL; -- index of next argument to read
   procedure Get_String
        (Item : out Ada.Strings.Unbounded.Unbounded_String;
         Expecting : in String := Default_Expecting);
>>

As an example of using in out parameters in generics.

Basically what is going on here is that the generic mechanism is being
used for partial parametrization. This is particularly convenient in
the case of in out parameters, since it is not possible to provide
defaults for in out parameters. Essentially the above generic defition
and an associated instantiation of it provides default in out parameters.

But i wonder if it is convincing. At least in this case? It seems
extremely unlikely that one would instantiation Get_String more than
once in a program, so why not just make it a package in which the
index is a local variable. Well I suppose you could say something
about task safety .. still ...





^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~1997-04-19  0:00 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1997-04-16  0:00 Generic in out object parameters petera
1997-04-17  0:00 ` Stephen Leake
1997-04-19  0:00   ` Robert Dewar
1997-04-18  0:00 ` Matthew Heaney

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