comp.lang.ada
 help / color / mirror / Atom feed
* Using Class wide types as factories, is this legit?
@ 2014-09-23  5:19 David Botton
  2014-09-23  7:23 ` Dmitry A. Kazakov
  0 siblings, 1 reply; 8+ messages in thread
From: David Botton @ 2014-09-23  5:19 UTC (permalink / raw)


I have a pattern I have used in the past to make Classwides act as factories for objects.

This worked in versions of GNAT about a year and a half ago. Is this a compiler bug or bad Ada?

The key line is:

Row  : Active_Record'Class := Template;

This is meant to act as a factory for new objects matching the Template class by duplicating Template on assignment to Row.

Code:
   type Active_Record
     (Table_Name : access constant String;
      Connection : access          Gnoga.Server.Database.Connection'Class)
     is new Ada.Finalization.Controlled with
      record
         Is_New     : Boolean                               := True;
         Fields     : Gnoga.Types.Data_Array_Type;
         Values     : Gnoga.Types.Data_Map_Type;
      end record;

   function Find_All
     (Template : Active_Record'Class;
      Like     : String := "";
      Order_By : String := "")
      return Active_Record_Array.Vector
   is
      use Ada.Strings.Unbounded;
      use Ada.Strings;

      SQL  : Unbounded_String :=
        To_Unbounded_String ("select * from ") & Template.Table_Name.all;
   begin
      if Like /= "" then
         SQL := SQL & " where " & Like;
      end if;

      if Order_By /= "" then
         SQL := SQL & " order by " & Order_By;
      end if;

      declare
         RS   : Gnoga.Server.Database.Recordset'Class :=
           Template.Connection.Query (To_String (SQL));

         Rows : Active_Record_Array.Vector;
         Row  : Active_Record'Class := Template;
      begin
         Row.Is_New := False;

         while RS.Next loop
            Row.Values := RS.Field_Values;
            Rows.Append (Row);
         end loop;

         RS.Close;
         return Rows;
      end;
   end Find_All;


On run the following error appears:
db_active(14597,0x7fff775fb310) malloc: *** error for object 0xc00007fe659d040f: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6


Using this work around removes the error, but limits the use of derived types of Active_Record being created by the assignment:

so replacing - Row  : Active_Record'Class := Template;

with:
         Row  : Active_Record (Template.Table_Name, Template.Connection);

All works.


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

end of thread, other threads:[~2014-09-24  7:22 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-23  5:19 Using Class wide types as factories, is this legit? David Botton
2014-09-23  7:23 ` Dmitry A. Kazakov
2014-09-23  8:21   ` David Botton
2014-09-23 19:28     ` Dmitry A. Kazakov
2014-09-23 21:27       ` David Botton
2014-09-24  7:22         ` Dmitry A. Kazakov
2014-09-23  8:37   ` briot.emmanuel
2014-09-23  8:52     ` David Botton

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