comp.lang.ada
 help / color / mirror / Atom feed
From: Adam Beneschan <adam@irvine.com>
Subject: Re: package Ada.Tags
Date: Thu, 7 Jun 2012 14:49:59 -0700 (PDT)
Date: 2012-06-07T14:49:59-07:00	[thread overview]
Message-ID: <2233e5f5-5e7f-44c3-aa91-801240385bab@googlegroups.com> (raw)
In-Reply-To: <0067e29b-aceb-4c50-9d62-453c4f549f2e@googlegroups.com>

On Thursday, June 7, 2012 1:36:32 PM UTC-7, RasikaSr...@gmail.com wrote:
> Friends
> 
> I have two types declared as follows:
> 
> with Ada.Calendar ;
> 
> package events is
>     type events_record_type is abstract tagged 
>       record
>          time : ada.Calendar.time ;
>       end record ;
>    procedure show(event : events_record_type) ;
>    
>    type basal_delivery_event_type is new events_record_Type with
>       record
>          amount : float ;
>       end record ;
>    overriding
>    procedure show( event : basal_delivery_event_type ) ;
>    
>    type bolus_delivery_event_type is new events_record_Type with
>       record
>          amount : float ;
>       end record ;
>    overriding
>    procedure show( event : bolus_delivery_event_type ) ;
>    
>    type SMBG_event_type is new events_record_type with
>       record
>          amount : short_integer ;
>       end record ;
>    overriding
>    procedure show( event : SMBG_event_type ) ;
>    
> end events ;
> 
> The following implementation in the body:
> 
> 
> 
>    procedure show (event : events_record_type) is
>       use GNAT.Calendar.Time_IO;  
>    begin      
>       put( ada.Tags.Expanded_Name( event'tag ) );      
>       put( gnat.Calendar.time_io.Image( event.time , gnat.Calendar.Time_IO.ISO_Date & " %T")) ;      
>    end show;
> 
> gives me a compilation error:
> 
> "tag" attribute can only be applied to objects of class - wide type.
> 
> In the above, isnt event an object meeting this criterion?

No.  Ada makes a distinction between specific types and class-wide types.  If a parameter is declared using a specific type, only objects of that type can be passed to it.  (This is different from what happens in, say, Java.)  What's happening here is that when you declare your derived types, the compiler inherits "show" from them, and declares a new version of "show" with a new specific type as a parameter--either basal_delivery_event_type, bolus_delivery_event_type, or SMBG_event_type.  If you don't override them, the code for the new routines will be the same as the code for the original routine, but using the new specific type.  When you dispatch, the program will call whichever routine has that specific type as a parameter.  But the type is still a specific type.  (Note: Although I'm describing this as if a new copy of the "show" routine is being created, the code should still be in your program only once.)

This is different from a routine with a class-wide parameter:

   procedure classwide_show (events : events_record_type'class);

Now, you can call this routine with any of your derived types as a parameter.  But this time, there's only one copy of the routine, not multiple copies as above.  Now, the routine can use events'tag to get information about the actual type of the object.  

But you can't do this in your example, because the show routine uses a specific type as a parameter.  However, you can get around it like this:

  put( ada.Tags.Expanded_Name( events_record_type'class(event)'tag ) );

In other words, tell the compiler to treat event as though it were a class-wide type, and it will be happy.

One other thing: You've declared overriding routines for show, but you didn't provide the bodies.  If you it to do the exact same thing as the "show" you declared for events_record_type, then don't override it--just let the program use the inherited copy.  If you want to have a body that performs the original "show" and does some other functions, then override it and have the body call this:

   events_record_type(event).show;  --or
   show (events_record_type (event));

That tells the compiler to treat event as though it had type events_record_type, and then it will pick the version of "show" that has an events_record_type parameter, i.e. the original one.  The 'Tag will still be the tag of whatever type you want, because 'Tag tells you what type the object really is, not what type you're telling the compiler to pretend it is.  

Hope this helps.  The paradigm in Ada is different from C++ or Java, so I think it takes some getting used to if you're coming from one of those languages.  But it's pretty simple to grasp once you get used to it.

                           -- Adam





      parent reply	other threads:[~2012-06-07 21:51 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-06-07 20:36 package Ada.Tags RasikaSrinivasan
2012-06-07 21:35 ` Simon Wright
2012-06-07 21:48   ` RasikaSrinivasan
2012-06-08  9:50   ` Yannick Duchêne (Hibou57)
2012-06-08  9:59     ` Dmitry A. Kazakov
2012-06-08 15:26     ` Adam Beneschan
2012-06-08 16:31     ` Simon Wright
2012-06-07 21:49 ` Adam Beneschan [this message]
replies disabled

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