comp.lang.ada
 help / color / mirror / Atom feed
* Can you help with an Ada 95 OO Problem
@ 1997-01-18  0:00 David Wallace
  1997-01-18  0:00 ` Matthew Heaney
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: David Wallace @ 1997-01-18  0:00 UTC (permalink / raw)



Hello

   I am attempting to get to grip with the new Ada 95 OO extensions, but 
   appear to be having a problem understanding correctly how views of, and
   dispatching of class wide type operations work on procedures which use
   an access parameter.

   Below is the example code I have been playing with to attempt to use the
   features I am experiencing problems with. The Noddy example is based
   around a simple OO abstraction of elements of a http protocol.

   The problem is described in the example source where the following text
   appears.

                ****** HELP ****

   Thanks,

       Davsid Wallace.


--
-- Start for main application.
--
with Http;
procedure Start is

begin

   Http.STart;

end Start;

--
-- Define Abstract Class to enforce Java/Eiffel style OO representation.
--
package Ada_Classes is

    type Ada_Class is abstract tagged null record;

    type Ada_Class_Access is access all Ada_Class'Class;

    function Create return Ada_Class_Access is abstract;


    procedure Init (Obj : access Ada_Class) is abstract;



end Ada_Classes;


--
-- Top Level Http Package
--
package Http is


   procedure Start;

end Http;

--
-- Internals to create object instances !!.
--
with Http.Headers.General_Headers;
package body Http is

   procedure Start is

        General_Header : Http.Headers.General_Headers.General_Header_Access
:=
        Http.Headers.General_Headers.Create;

   begin

        --
        -- Initialise an instance of a general Header.
        --
        -- Here I have attempted to initialise the General Header Instance,
        -- which would also attempt to initialise its parent type component.
        --
        Http.Headers.General_Headers.Init (Obj => General_Header);

   end Start;


end Http;
     

--
-- This package is simply to define the
with Ada_Classes;
package Http.Headers is

   type Header is new Ada_Classes.Ada_Class with  private; 

   type Header_Access is access all Header'Class;

   function Create return Header_Access;
   
   procedure init(Obj : access Header);

   procedure Debug(Obj : access Header);

private

   type Header is new Ada_Classes.Ada_Class with 
      record
         Header_Data : Integer;
      end record ;

end Http.Headers;

with Text_Io;
package body  Http.Headers is

   function Create return Header_Access is

      New_Header : Header_Access;

   begin

      Text_Io.Put_Line("Allocatting Header Instance");
      New_Header := new Header'(Header_Data => 0);

      return New_Header;

   end Create;
   
   procedure init(Obj : access Header) is

   begin
      Text_Io.Put_Line("Header Object has be initialised");
      --
      -- Initialise the Header Data object with an abritary value.
      --
      Obj.Header_Data := 4;

   end Init;

end Http.Headers;

package Http.Headers.General_Headers is

   type General_Header is new Headers.Header with private;
   type General_Header_Access is access all General_Header'Class;

   function Create return General_Header_Access;

   procedure init(Obj : access General_Header);

private

   type General_Header is new Headers.Header with
      record
         General_Header_Data : Integer;
      end record ;

end Http.Headers.General_Headers;

with Text_Io;
package body Http.Headers.General_Headers is

   function Create return General_Header_Access is

      New_General_Header : General_Header_Access;

   begin

      Text_Io.Put_Line("Allocatting General_Header Instance");

      New_General_Header := new General_Header;

      return New_General_Header;

   end Create;

   procedure init(Obj : access General_Header)is

      Header_Ref : Header_Access := Obj;

   begin


      --
      -- Init Standard Header Component.
      --
      Text_Io.Put_Line("General Header initialising Header Object");

      -- ***************** HELP *********** HELP ***************************
      --
      -- This is the crux of the problem.
      --
      -- How do I get the General_Header to Init the Header component of
      -- the parent type Header, using its Init operation.
      --
      -- The Call below invokes Infinite recursion to the operation,
      -- Http.Headers.General_Header, even though the parent operation
      -- is referenced.
      --
      -- I assume the Class Wide Type is using the Tag of the Created object
      -- to dispatch on the operation Http.Headers.General_Headers.Init.
      -- I initialy believed that the Conversion of Header_Access on the
access
      -- parameter would, allow it to have the correct view on the classwide
      -- type, and dispatch the appropriate problem.
      --
      -- Can anybody put me on the right path please. Use of access
parameters
      -- on this procedure appears to be confusing the matter. I would
      -- appreciate your help, since this problem has been giving me a
headache
      -- for a couple of days now.
      --
      -- NB.
      --    I know the Header component is visible from this procedure,
      --    and can be directly assigned, but that is not what I am trying
to
      --    achieve. This would not have been the case If I had not used
Child
      --    Libraries.
      --
      -- ***************** HELP *********** HELP ***************************
      --
      Http.Headers.Init(Obj => Header_Ref);

      Text_Io.Put_Line("General Header Object has be initialised");

      Obj.General_Header_Data := 4;


   end Init;


   procedure Debug(Obj : access Header)is

   begin

      Text_Io.Put_Line
        ("Obj.Header      => " &
         Integer'Image (Obj.Header_Data));

      Text_Io.Put_Line
        ("Obj.General_Header      => " &
         Integer'Image (Obj.General_Header_Data));

   end Debug;

end Http.Headers.General_Headers;
     
              

--
--. --. --. --. : : --- --- .---------------------------------------------.
|_| |_| | _ | | | | |_   |  |Internet provider for all Acorn RISC machines|
| | |\  | | | | |\| |    |  '---------------------------------------------'
| | | \ |_| |_| | | |__  |  averon@argonet.co.uk






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

* Re: Can you help with an Ada 95 OO Problem
  1997-01-18  0:00 Can you help with an Ada 95 OO Problem David Wallace
@ 1997-01-18  0:00 ` Matthew Heaney
  1997-01-19  0:00 ` David Wallace
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Matthew Heaney @ 1997-01-18  0:00 UTC (permalink / raw)



In article <na.9173d8474e.a50140averon@argonet.co.uk>, David Wallace
<averon@argonet.co.uk> wrote:


>      -- ***************** HELP *********** HELP ***************************
>      --
>      Http.Headers.Init(Obj => Header_Ref);
>
>      Text_Io.Put_Line("General Header Object has be initialised");
>
>      Obj.General_Header_Data := 4;

My Ada95 is a little weak, so I might give you bad info.

The subprogram reference "Http.Headers.Init" doesn't refer to the
superclass implementation of that subprogram, it merely refers to the
specification of the subprogram.  The implementation of course can be
overridden by any descendant.

This appears to be what has happened here.  You called a primitive
operation with an argument of type General_Headers, not Headers, so the
overridden subprogram is what gets called, and in this case infinate
recursion was the result.

This seems awkward at first; refering to the "specification" of the
primitive operation by a different module reference than  the module
containing the implementation.  In fact, Mitch Gart criticized this
language "feature" a while back.  

The trick is always asking, What is the type of the object passed to the
operation?  It's the object that determines what operation gets dispatched
at runtime, not the reference to the *specification* of the operation.

Try a view conversion of the designated object, to get at its primitive
operation:

   Http.Headers.Init (Obj => Http.Headers.Header (Header_Ref.all));

I'm not sure that will work, but try it and let me know (so I can learn, too!).

There was some debate a while back about how to invoke the parent's
implementation of the operation.  There was one case (cited by Mitch) that
required a very un-obvious technique.  Perhaps your difficulties mean
direct language support for "invoke parent's method" would be useful after
all.

matt

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




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

* Re: Can you help with an Ada 95 OO Problem
  1997-01-18  0:00 Can you help with an Ada 95 OO Problem David Wallace
  1997-01-18  0:00 ` Matthew Heaney
@ 1997-01-19  0:00 ` David Wallace
  1997-01-21  0:00   ` Can you help with an Ada 95 OO Problem (Solution !!!) David Wallace
  1997-01-20  0:00 ` Can you help with an Ada 95 OO Problem Jon S Anthony
  1997-01-21  0:00 ` Jerome Desquilbet
  3 siblings, 1 reply; 6+ messages in thread
From: David Wallace @ 1997-01-19  0:00 UTC (permalink / raw)



Thanks for your reply Mathew,

   On Sat 18 Jan 97 (20:26:24), mheaney@ni.net wrote:#   >
   >Try a view conversion of the designated object, to get at its primitive
   >operation:
   >
   >   Http.Headers.Init (Obj => Http.Headers.Header (Header_Ref.all));
   >
   >I'm not sure that will work, but try it and let me know (so I can
   >learn, too!).
   >  

   I had tried your suggestion above, but this will not work either. Since
   the Init operation has an access parameter, it can only be passed an 
   access type, but giving the components of the object direct visibility. 
   This is why I had tried using the type conversion Headers_Access on the 
   access parameter
   
    procedure Init (Obj : access General_Header) is

         Header_Ref : Header_Access(Obj);


   begin

      --
      -- I thought that by doing the view conversion with the acces type,
      -- the tag would be changed on the class wide type. But on 
      -- Investigation I found that this was not the case, the tag for the 
      -- class wide type, would stay the same (In John Barnes Ada 95 book). 
      -- This was when I really found myself stumped.
      --
      -- The problem is made more difficult using the access parameter, which

      -- insists on an allocated access_type being passed in. I think it 
      -- would be an easier problem to understand if it were not an access 
      -- parameter.
      --
      Init(Obj => Header_Ref);

   end Init;
        

   If you have any further Ideas, please do not hesitate to reply again. 
   I am still reading the text books to try and find out, but would still 
   appreciate help.


   Thanks

       Dave Wallace.

--
--. --. --. --. : : --- --- .---------------------------------------------.
|_| |_| | _ | | | | |_   |  |Internet provider for all Acorn RISC machines|
| | |\  | | | | |\| |    |  '---------------------------------------------'
| | | \ |_| |_| | | |__  |  averon@argonet.co.uk






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

* Re: Can you help with an Ada 95 OO Problem
  1997-01-18  0:00 Can you help with an Ada 95 OO Problem David Wallace
  1997-01-18  0:00 ` Matthew Heaney
  1997-01-19  0:00 ` David Wallace
@ 1997-01-20  0:00 ` Jon S Anthony
  1997-01-21  0:00 ` Jerome Desquilbet
  3 siblings, 0 replies; 6+ messages in thread
From: Jon S Anthony @ 1997-01-20  0:00 UTC (permalink / raw)



In article <mheaney-ya023280001801972026220001@news.ni.net> mheaney@ni.net (Matthew Heaney) writes:

> Try a view conversion of the designated object, to get at its primitive
> operation:
> 
>    Http.Headers.Init (Obj => Http.Headers.Header (Header_Ref.all));
> 
> I'm not sure that will work, but try it and let me know (so I can learn, too!).

He doesn't have a "non-access" parameter version of the operation, so
you need to add a 'Access to the converted object.  That should work,
but you can make it simpler.  Just,

   Http.Headers.Init (Obj => Http.Headers.Header(Obj.all)'Access);

The new access object is irrelevant.


> There was some debate a while back about how to invoke the parent's
> implementation of the operation.  There was one case (cited by Mitch) that
> required a very un-obvious technique.  Perhaps your difficulties mean

I think that had to do with "smoothly" changing the parent (by adding
in an intermediate).  This is fixed by using a subtype.  Works just
fine.  I suppose the 'Parent thing would look a little nicer...

/Jon

-- 
Jon Anthony
Organon Motives, Inc.
Belmont, MA 02178
617.484.3383
jsa@organon.com





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

* Re: Can you help with an Ada 95 OO Problem
  1997-01-18  0:00 Can you help with an Ada 95 OO Problem David Wallace
                   ` (2 preceding siblings ...)
  1997-01-20  0:00 ` Can you help with an Ada 95 OO Problem Jon S Anthony
@ 1997-01-21  0:00 ` Jerome Desquilbet
  3 siblings, 0 replies; 6+ messages in thread
From: Jerome Desquilbet @ 1997-01-21  0:00 UTC (permalink / raw)
  To: David Wallace


David,

First, some comments about the compilability of the program you posted:

- You have to supply a body for Http.Headers.Debug

- The body Http.Headers.General_Headers.Init does not compile because in

    procedure Init (Obj : access General_Header) is
	Header_Ref : Header_Access := Obj;
    begin
        ...
    end Init;

  "OBJ is not a value of HEADER_ACCESS"

- There's another semantic problem in Http.Headers.General_Headers.Debug

I don't know if I well understood your problem. However, I have built a
program handling something similar (again if I understood well).
I.e. how to initialize an object, starting by initializing its "inner
parent object".
I don't think I would create and initialize objects exactely like that,
but never mind. I hope this example will help you.

Good luck,

  J�r�me.


package Base is

    type Object is tagged private;
    procedure Initialize (A_Base : access Object);
    procedure Debug (A_Base : in Object);

private
    type Object is tagged
	record
	    Data : Integer;
	end record;
end Base;


with Ada.Text_Io;

package body Base is

    Arbitrary_Data : constant Integer := 4;

    procedure Initialize (A_Base : access Object) is
    begin
	Ada.Text_Io.Put_Line ("Initializing a base object... begin");
	A_Base.all.Data := Arbitrary_Data;
	Ada.Text_Io.Put_Line ("Initializing a base object... end");
    end Initialize;

    procedure Debug (A_Base : in Object) is
    begin
	Ada.Text_Io.Put_Line (Integer'Image (A_Base.Data));
    end Debug;

end Base;


with Base;

package Derived is

    type Object is new Base.Object with private;
    procedure Initialize (A_Derived : access Object);
    procedure Debug (A_Derived : in Object);

private
    type Object is new Base.Object with
	record
	    Data : Character;
	end record;
end Derived;


with Ada.Text_Io;

package body Derived is

    Arbitrary_Data : constant Character := 'e';

    procedure Initialize (A_Derived : access Object) is
    begin
	Ada.Text_Io.Put_Line ("Initializing a derived object... begin");
	Base.Initialize (Base.Object (A_Derived.all)'Access);
	A_Derived.all.Data := Arbitrary_Data;
	Ada.Text_Io.Put_Line ("Initializing a derived object... end");
    end Initialize;

    procedure Debug (A_Derived : in Object) is
    begin
	Base.Debug (Base.Object (A_Derived));
	Ada.Text_Io.Put (A_Derived.Data);
	Ada.Text_Io.New_Line;
    end Debug;

end Derived;


with Derived;

procedure Try_Derived is
    D : aliased Derived.Object;
begin
    Derived.Initialize (D'Access);
    Derived.Debug (D);
end Try_Derived;

______________________________________________________________________
Jerome Desquilbet                             jDesquilbet@Rational.COM
 ' ^




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

* Re: Can you help with an Ada 95 OO Problem (Solution !!!)
  1997-01-19  0:00 ` David Wallace
@ 1997-01-21  0:00   ` David Wallace
  0 siblings, 0 replies; 6+ messages in thread
From: David Wallace @ 1997-01-21  0:00 UTC (permalink / raw)



Thanks to Jon and JDesquilbet for the solution.

   The answer is to make the call to the parent type operation as follows:

   Htt.Headers.Init(Obj => Header(Obj.all)'Access);

   Obj.all is the object. Header(Obj.all) _converts_ towards the _root_
   (perfectly safe) and the 'Access generates the access value for the
   call on the parent operation.


   Many thanks,

         Dave Wallace

--
--. --. --. --. : : --- --- .---------------------------------------------.
|_| |_| | _ | | | | |_   |  |Internet provider for all Acorn RISC machines|
| | |\  | | | | |\| |    |  '---------------------------------------------'
| | | \ |_| |_| | | |__  |  averon@argonet.co.uk






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

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

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1997-01-18  0:00 Can you help with an Ada 95 OO Problem David Wallace
1997-01-18  0:00 ` Matthew Heaney
1997-01-19  0:00 ` David Wallace
1997-01-21  0:00   ` Can you help with an Ada 95 OO Problem (Solution !!!) David Wallace
1997-01-20  0:00 ` Can you help with an Ada 95 OO Problem Jon S Anthony
1997-01-21  0:00 ` Jerome Desquilbet

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