comp.lang.ada
 help / color / mirror / Atom feed
* Experimenting with the OOP features in Ada
@ 2017-01-02 13:21 Laurent
  2017-01-02 14:11 ` Brian Drummond
  2017-01-02 16:41 ` Dmitry A. Kazakov
  0 siblings, 2 replies; 24+ messages in thread
From: Laurent @ 2017-01-02 13:21 UTC (permalink / raw)


Hi

Happy new year!

Trying some OOP features in Ada. So not sure if everything is actually
correct.
Comments are welcome.

So I have done a little test. Link at the end.
I get the following error:

raised CONSTRAINT_ERROR : my_strings-handle.adb:14 access check failed

Which I don't understand. Sounds like the object no longer exists?

test.adb:

with Ada.Text_IO;
with Ada.Exceptions;

with Gnat.Traceback.Symbolic; use Gnat;

with Base_Types.Antibiotics;
with My_Strings;
with My_Strings.Handle;

procedure Test is

   package SS renames My_Strings.Handle;

   Test_Antibiotic : Base_Types.Antibiotics.Object
:=Base_Types.Antibiotics.Create (Name     => "Test Antibiotic 1", 
   Code_SIL =>"123", 
   CMI      => "1", 
   SIR      => "S");
   
   Test_String     : My_Strings.Handle.My_Safe_String := SS.Create ("Test
single 1");
   
begin

   Ada.Text_IO.Put_Line (Test_String.Value);
   Test_String := SS.Create ("Test single 2");
   Ada.Text_IO.Put_Line (Test_String.Value);
   Test_String := SS.Create ("Test single 3");
   Ada.Text_IO.Put_Line (Test_String.Value);
   Ada.Text_IO.Put_Line (Test_String.Value);
   Ada.Text_IO.New_Line;

   Ada.Text_IO.Put_Line ("Test record run 1:");
   Ada.Text_IO.New_Line;

   Ada.Text_IO.Put_Line ("Name: " & Test_Antibiotic.Name_Value);
   Ada.Text_IO.Put_Line ("Code SIL: " & Test_Antibiotic.Code_SIL_Value);
   Ada.Text_IO.Put_Line ("CMI: " & Test_Antibiotic.CMI_Value);
   Ada.Text_IO.Put_Line ("SIR: " & Test_Antibiotic.SIR_Value);
   Ada.Text_IO.New_Line;
   
   Ada.Text_IO.Put_Line ("Test record run 2:");
   Ada.Text_IO.New_Line;
   
   Test_Antibiotic := Base_Types.Antibiotics.Create_Name (Name => "Test
Antibiotic 2");
   Ada.Text_IO.Put_Line ("Name: " & Test_Antibiotic.Name_Value);

   Test_Antibiotic := Base_Types.Antibiotics.Create_Code_SIL (Code_SIL =>
"amc");
   Ada.Text_IO.Put_Line ("Code SIL: " & Test_Antibiotic.Code_SIL_Value);

   Test_Antibiotic := Base_Types.Antibiotics.Create_CMI (CMI => "2");
   Ada.Text_IO.Put_Line ("CMI: " & Test_Antibiotic.CMI_Value);      
      
   Test_Antibiotic := Base_Types.Antibiotics.Create_SIR (SIR => "R");
   Ada.Text_IO.Put_Line ("SIR: " & Test_Antibiotic.SIR_Value);
   Ada.Text_IO.New_Line;
   
   Ada.Text_IO.Put_Line ("Test record run 3:");
   Ada.Text_IO.New_Line;

   Test_Antibiotic := Base_Types.Antibiotics.Create_Name (Name => "Test
Antibiotic 3");   
   Test_Antibiotic := Base_Types.Antibiotics.Create_Code_SIL (Code_SIL =>
"gen");   
   Test_Antibiotic := Base_Types.Antibiotics.Create_CMI (CMI => "8");
   Test_Antibiotic := Base_Types.Antibiotics.Create_SIR (SIR => "I");
   
   Ada.Text_IO.Put_Line ("Print run 3:");

   Ada.Text_IO.Put_Line ("Name: " & Test_Antibiotic.Name_Value);   
   Ada.Text_IO.Put_Line ("Code SIL: " & Test_Antibiotic.Code_SIL_Value);
   Ada.Text_IO.Put_Line ("CMI: " & Test_Antibiotic.CMI_Value);
   Ada.Text_IO.Put_Line ("SIR: " & Test_Antibiotic.SIR_Value);
   
   exception

   when Err : others =>
      Ada.Text_IO.Put_Line ("Problem: " &
                              Ada.Exceptions.Exception_Information (Err));

      Ada.Text_IO.Put_Line (Traceback.Symbolic.Symbolic_Traceback (Err));
   
end Test;

Terminal output:

Test single 1
Test single 2
Test single 3
Test single 3

Test record run 1:

Name: Test Antibiotic 1
Code SIL: 123
CMI: 1
SIR: S

Test record run 2:

Name: Test Antibiotic 2
Code SIL: amc
CMI: 2
SIR: R

Test record run 3:

Print run 3:
Problem: raised CONSTRAINT_ERROR : my_strings-handle.adb:14 access check
failed


Why does it fail on the 3rd run? It works the 2 first ones?

The programm depends on Dmitry A. Kazakov's Simple Components.
The My_Strings package is copied from the docs of this library.

Link to the files on Git:

https://github.com/Chutulu/BCI_2.git

Thanks

Laurent

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

* Re: Experimenting with the OOP features in Ada
  2017-01-02 13:21 Experimenting with the OOP features in Ada Laurent
@ 2017-01-02 14:11 ` Brian Drummond
  2017-01-02 14:43   ` Brian Drummond
  2017-01-02 15:54   ` Laurent
  2017-01-02 16:41 ` Dmitry A. Kazakov
  1 sibling, 2 replies; 24+ messages in thread
From: Brian Drummond @ 2017-01-02 14:11 UTC (permalink / raw)


On Mon, 02 Jan 2017 05:21:49 -0800, Laurent wrote:

> Hi
> 
> Happy new year!
> 
> Trying some OOP features in Ada. So not sure if everything is actually
> correct.
> Comments are welcome.
> 
> So I have done a little test. Link at the end.
> I get the following error:
> 
> raised CONSTRAINT_ERROR : my_strings-handle.adb:14 access check failed
> 
> Which I don't understand. Sounds like the object no longer exists?


   Test_Antibiotic := Base_Types.Antibiotics.Create_Name 
          (Name => "Test Antibiotic 3");
   Test_Antibiotic := Base_Types.Antibiotics.Create_Code_SIL 
          (Code_SIL => "gen");
   Test_Antibiotic := Base_Types.Antibiotics.Create_CMI (CMI => "8");
   Test_Antibiotic := Base_Types.Antibiotics.Create_SIR (SIR => "I");

Looks like you're creating 4 new Base_Types.Antibiotics.Objects here and 
discarding the first three. 

The fourth has whatever the default is for its Name, instead of "Test 
Antibiotic 3", whose owner got discarded.

I suspect you intended something more like

   Test_Antibiotic := Base_Types.Antibiotics.Create_Name (Name => "Test 
Antibiotic 3");
   Test_Antibiotic.Set_Code_SIL (Code_SIL => "gen");
   Test_Antibiotic.Set_CMI (CMI => "8");
   Test_Antibiotic.Set_SIR (SIR => "I");

or even another call to the all-in-one Create you used initially.

-- Brian


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

* Re: Experimenting with the OOP features in Ada
  2017-01-02 14:11 ` Brian Drummond
@ 2017-01-02 14:43   ` Brian Drummond
  2017-01-02 16:27     ` Laurent
       [not found]     ` <85ef59f3-bcbe-4630-9b4d-8285623ab456@googlegroups.com>
  2017-01-02 15:54   ` Laurent
  1 sibling, 2 replies; 24+ messages in thread
From: Brian Drummond @ 2017-01-02 14:43 UTC (permalink / raw)


On Mon, 02 Jan 2017 14:11:40 +0000, Brian Drummond wrote:

> On Mon, 02 Jan 2017 05:21:49 -0800, Laurent wrote:
> 
> I suspect you intended something more like
> 
>    Test_Antibiotic := Base_Types.Antibiotics.Create_Name (Name => "Test
> Antibiotic 3");
>    Test_Antibiotic.Set_Code_SIL (Code_SIL => "gen");

More specifically, especially if you're used to some other OO languages, 
is that Ada (2005 and 2012) handle the object.method notation a little 
differently than you may be used to.

You've written a function

   function Create_Code_SIL (Code_SIL : String) return Object;

which takes ONE argument "Code_Sil" and creates a new object containing 
it, and three empty elements...

You were probably expecting a silent "this" argument ... sorry, Ada 
doesn't do that, you explicitly pass the receiver (or "self" or "this") 
to the method (as the Linn Lingo language did).

So a function to set Code_SIL on an existing object would look more like

function Create_Code_SIL (This : Base_Types.Antibiotics.Objects;
                          Code_SIL : String) return Object;

and its implementation

function Create_Code_SIL (This : Base_Types.Antibiotics.Objects;
                          Code_SIL : String) return Object
   is
   begin
      This.Code_SIL := My_Strings.Handle.Create (Value => Code_SIL);
      return This;
   end Create_Code_SIL;

or a Procedure version (the Set_* procedure in my previous post) with an 
In Out parameter called This.

Procedure Set_Code_SIL (This : in out Base_Types.Antibiotics.Objects;
                        Code_SIL => "gen");

Now your function can be called either in traditional Ada-95 syntax with 
both arguments in the argument list, or object.method notation with only 
the second argument. This allows Ada-95 programs to be more easily and 
gradually refactored into Ada-2005 or 2012.

So the following are equivalent:

Test_Antibiotic := Base_Types.Antibiotics.Create_Code_SIL (
                             This => Test_Antibiotic,
                             Code_SIL => "Test Antibiotic 3")

Test_Antibiotic := Test_Antibiotic.Create_Code_SIL 
                            (Code_SIL => "Test Antibiotic 3"); 

but the preferred form would be

Test_Antibiotic.Set_Code_SIL (Code_SIL => "gen");

-- Brian

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

* Re: Experimenting with the OOP features in Ada
  2017-01-02 14:11 ` Brian Drummond
  2017-01-02 14:43   ` Brian Drummond
@ 2017-01-02 15:54   ` Laurent
  1 sibling, 0 replies; 24+ messages in thread
From: Laurent @ 2017-01-02 15:54 UTC (permalink / raw)


On Monday, 2 January 2017 15:13:12 UTC+1, Brian Drummond  wrote:
> On Mon, 02 Jan 2017 05:21:49 -0800, Laurent wrote:
> 
> > Hi
> > 
> > Happy new year!
> > 
> > Trying some OOP features in Ada. So not sure if everything is actually
> > correct.
> > Comments are welcome.
> > 
> > So I have done a little test. Link at the end.
> > I get the following error:
> > 
> > raised CONSTRAINT_ERROR : my_strings-handle.adb:14 access check failed
> > 
> > Which I don't understand. Sounds like the object no longer exists?
> 
> 
>    Test_Antibiotic := Base_Types.Antibiotics.Create_Name 
>           (Name => "Test Antibiotic 3");
>    Test_Antibiotic := Base_Types.Antibiotics.Create_Code_SIL 
>           (Code_SIL => "gen");
>    Test_Antibiotic := Base_Types.Antibiotics.Create_CMI (CMI => "8");
>    Test_Antibiotic := Base_Types.Antibiotics.Create_SIR (SIR => "I");
> 
> Looks like you're creating 4 new Base_Types.Antibiotics.Objects here and 
> discarding the first three. 
> 
> The fourth has whatever the default is for its Name, instead of "Test 
> Antibiotic 3", whose owner got discarded.
> 
> I suspect you intended something more like
> 
>    Test_Antibiotic := Base_Types.Antibiotics.Create_Name (Name => "Test 
> Antibiotic 3");
>    Test_Antibiotic.Set_Code_SIL (Code_SIL => "gen");
>    Test_Antibiotic.Set_CMI (CMI => "8");
>    Test_Antibiotic.Set_SIR (SIR => "I");
> 
> or even another call to the all-in-one Create you used initially.
> 
> -- Brian

Actually I am just trying to update the different parts of Test_Antibiotic.

Create... = Set and Value... = Get

But those names are used in the SimpleComponents and its doc so I tried to
stick to this naming to not get confused. Which failed

The all-in-one Create I would have called Make...

Test_Antibiotic.Create_Whatever (Whatever =>...) doesn't work. Those are
functions not procedures. Was the first thing which I tried and got me
confused too.

But the naming shouldn't influence the behaviour, should it?


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

* Re: Experimenting with the OOP features in Ada
  2017-01-02 14:43   ` Brian Drummond
@ 2017-01-02 16:27     ` Laurent
  2017-01-03 13:01       ` Brian Drummond
       [not found]     ` <85ef59f3-bcbe-4630-9b4d-8285623ab456@googlegroups.com>
  1 sibling, 1 reply; 24+ messages in thread
From: Laurent @ 2017-01-02 16:27 UTC (permalink / raw)


On Monday, 2 January 2017 15:44:57 UTC+1, Brian Drummond  wrote:
> On Mon, 02 Jan 2017 14:11:40 +0000, Brian Drummond wrote:
> So the following are equivalent:
> 
> Test_Antibiotic := Base_Types.Antibiotics.Create_Code_SIL (
>                              This => Test_Antibiotic,
>                              Code_SIL => "Test Antibiotic 3")
> 
> Test_Antibiotic := Test_Antibiotic.Create_Code_SIL 
>                             (Code_SIL => "Test Antibiotic 3"); 
> 
> but the preferred form would be
> 
> Test_Antibiotic.Set_Code_SIL (Code_SIL => "gen");
> 
> -- Brian

Yes last one looks nice but doesn't work. No selector... Object is private.
So 2nd one.
Now I won't compile because Base_Types.Object is abstract. So I have to
figure out how/where to put the overriding works. In John Barnes Book it
looks so easy and light. Doing it myself feels clumsy :( 

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

* Re: Experimenting with the OOP features in Ada
  2017-01-02 13:21 Experimenting with the OOP features in Ada Laurent
  2017-01-02 14:11 ` Brian Drummond
@ 2017-01-02 16:41 ` Dmitry A. Kazakov
  2017-01-02 18:50   ` Laurent
  1 sibling, 1 reply; 24+ messages in thread
From: Dmitry A. Kazakov @ 2017-01-02 16:41 UTC (permalink / raw)


On 2017-01-02 14:21, Laurent wrote:

> Trying some OOP features in Ada. So not sure if everything is actually
> correct.
> Comments are welcome.
>
> So I have done a little test. Link at the end.
> I get the following error:
>
> raised CONSTRAINT_ERROR : my_strings-handle.adb:14 access check failed
>
> Which I don't understand. Sounds like the object no longer exists?
>
> test.adb:
>
> with Ada.Text_IO;
> with Ada.Exceptions;
>
> with Gnat.Traceback.Symbolic; use Gnat;
>
> with Base_Types.Antibiotics;
> with My_Strings;
> with My_Strings.Handle;
>
> procedure Test is
>
>    package SS renames My_Strings.Handle;
>
>    Test_Antibiotic : Base_Types.Antibiotics.Object
> :=Base_Types.Antibiotics.Create (Name     => "Test Antibiotic 1",
>    Code_SIL =>"123",
>    CMI      => "1",
>    SIR      => "S");
>
>    Test_String     : My_Strings.Handle.My_Safe_String := SS.Create ("Test
> single 1");
>
> begin
>
>    Ada.Text_IO.Put_Line (Test_String.Value);
>    Test_String := SS.Create ("Test single 2");
>    Ada.Text_IO.Put_Line (Test_String.Value);
>    Test_String := SS.Create ("Test single 3");
>    Ada.Text_IO.Put_Line (Test_String.Value);
>    Ada.Text_IO.Put_Line (Test_String.Value);
>    Ada.Text_IO.New_Line;
>
>    Ada.Text_IO.Put_Line ("Test record run 1:");
>    Ada.Text_IO.New_Line;
>
>    Ada.Text_IO.Put_Line ("Name: " & Test_Antibiotic.Name_Value);
>    Ada.Text_IO.Put_Line ("Code SIL: " & Test_Antibiotic.Code_SIL_Value);
>    Ada.Text_IO.Put_Line ("CMI: " & Test_Antibiotic.CMI_Value);
>    Ada.Text_IO.Put_Line ("SIR: " & Test_Antibiotic.SIR_Value);
>    Ada.Text_IO.New_Line;
>
>    Ada.Text_IO.Put_Line ("Test record run 2:");
>    Ada.Text_IO.New_Line;
>
>    Test_Antibiotic := Base_Types.Antibiotics.Create_Name (Name => "Test
> Antibiotic 2");
>    Ada.Text_IO.Put_Line ("Name: " & Test_Antibiotic.Name_Value);
>
>    Test_Antibiotic := Base_Types.Antibiotics.Create_Code_SIL (Code_SIL =>
> "amc");
>    Ada.Text_IO.Put_Line ("Code SIL: " & Test_Antibiotic.Code_SIL_Value);
>
>    Test_Antibiotic := Base_Types.Antibiotics.Create_CMI (CMI => "2");
>    Ada.Text_IO.Put_Line ("CMI: " & Test_Antibiotic.CMI_Value);
>
>    Test_Antibiotic := Base_Types.Antibiotics.Create_SIR (SIR => "R");
>    Ada.Text_IO.Put_Line ("SIR: " & Test_Antibiotic.SIR_Value);
>    Ada.Text_IO.New_Line;
>
>    Ada.Text_IO.Put_Line ("Test record run 3:");
>    Ada.Text_IO.New_Line;
>
>    Test_Antibiotic := Base_Types.Antibiotics.Create_Name (Name => "Test
> Antibiotic 3");
>    Test_Antibiotic := Base_Types.Antibiotics.Create_Code_SIL (Code_SIL =>
> "gen");
>    Test_Antibiotic := Base_Types.Antibiotics.Create_CMI (CMI => "8");
>    Test_Antibiotic := Base_Types.Antibiotics.Create_SIR (SIR => "I");
>
>    Ada.Text_IO.Put_Line ("Print run 3:");
>
>    Ada.Text_IO.Put_Line ("Name: " & Test_Antibiotic.Name_Value);
>    Ada.Text_IO.Put_Line ("Code SIL: " & Test_Antibiotic.Code_SIL_Value);
>    Ada.Text_IO.Put_Line ("CMI: " & Test_Antibiotic.CMI_Value);
>    Ada.Text_IO.Put_Line ("SIR: " & Test_Antibiotic.SIR_Value);
>
>    exception
>
>    when Err : others =>
>       Ada.Text_IO.Put_Line ("Problem: " &
>                               Ada.Exceptions.Exception_Information (Err));
>
>       Ada.Text_IO.Put_Line (Traceback.Symbolic.Symbolic_Traceback (Err));
>
> end Test;
>
> Terminal output:
>
> Test single 1
> Test single 2
> Test single 3
> Test single 3
>
> Test record run 1:
>
> Name: Test Antibiotic 1
> Code SIL: 123
> CMI: 1
> SIR: S
>
> Test record run 2:
>
> Name: Test Antibiotic 2
> Code SIL: amc
> CMI: 2
> SIR: R
>
> Test record run 3:
>
> Print run 3:
> Problem: raised CONSTRAINT_ERROR : my_strings-handle.adb:14 access check
> failed
>
>
> Why does it fail on the 3rd run? It works the 2 first ones?

You create a new object each time you make assignment. So at the line 42 
Create_Name creates an object with Name set. Then at the line 45 
Create_Code_SIL overwrites that object with another instance with no 
name set. When you try to get its name, the handle of the string is 
invalid. An attempt to get the value of gives Constraint_Error.

P.S. If you want to set components individually you must either expose 
them or else provide setters.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

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

* Re: Experimenting with the OOP features in Ada
  2017-01-02 16:41 ` Dmitry A. Kazakov
@ 2017-01-02 18:50   ` Laurent
  2017-01-02 20:55     ` Dmitry A. Kazakov
  0 siblings, 1 reply; 24+ messages in thread
From: Laurent @ 2017-01-02 18:50 UTC (permalink / raw)


On Monday, 2 January 2017 17:41:19 UTC+1, Dmitry A. Kazakov  wrote:
> 
> You create a new object each time you make assignment. So at the line
> 42 
> Create_Name creates an object with Name set. Then at the line 45 
> Create_Code_SIL overwrites that object with another instance with no 
> name set. When you try to get its name, the handle of the string is 
> invalid. An attempt to get the value of gives Constraint_Error.
> 
> P.S. If you want to set components individually you must either expose
> 
> them or else provide setters.
> 
> -- 
> Regards,
> Dmitry A. Kazakov
> http://www.dmitry-kazakov.de
> 
Then why didn't it fail immediately on the first run? Antibiotics is a
record with 4 of those lazy Safe String objects. 

Name/=Code_SIL/=CMI/=SIR

Each one has its own Create/Value function. 
Wasn't sure/ had expected (big mistake as always) that I could somehow
use the Create/Value functions from Safe String without having to write
additional code. 

The test was actually to figure out how it would work and if it would
make a difference compared with the Unbounded_Strings package and with
the old version.

I am quite tempted in using the persistent storage capabilities of
Simple Components but that means that I have to adapt my program to the
style of this library. Don't think that it would be possible to only graft it
at the latest moment?

Now with (Item : in out Something) parameter  and adding an "overriding"
it works. Not really clear what changed. Perhaps the overriding? 

BTW what is the reach of the overriding keyword i.e.:

   overriding
   function Create_Name (Item : in out Object; Name : String) return
Object;
   function Create_Code_SIL (Item : in out Object; Code_SIL : String)
return Object;
   function Create_CMI (Item : in out Object; CMI : String) return
Object;
   function Create_SIR (Item : in out Object; SIR : String) return
Object;

   function Create (Item                      : in out Object;
                    Name                      : String;
                    Code_SIL                  : String;
                    CMI                       : String;
                    SIR                       : String) return Object;

private

   type Object is new Base_Types.Object with
      record
         CMI : My_Strings.Handle.My_Safe_String;
         SIR : My_Strings.Handle.My_Safe_String;
      end record;

end Base_Types.Antibiotics;

Gnat was only complaining that Create_Name needs overriding even if
Create_Code_SIL is also in the Base_Type which is abstract.

Thanks


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

* Re: Experimenting with the OOP features in Ada
  2017-01-02 18:50   ` Laurent
@ 2017-01-02 20:55     ` Dmitry A. Kazakov
  2017-01-03 13:39       ` Laurent
  0 siblings, 1 reply; 24+ messages in thread
From: Dmitry A. Kazakov @ 2017-01-02 20:55 UTC (permalink / raw)


On 2017-01-02 19:50, Laurent wrote:
> On Monday, 2 January 2017 17:41:19 UTC+1, Dmitry A. Kazakov  wrote:
>>
>> You create a new object each time you make assignment. So at the line
>> 42
>> Create_Name creates an object with Name set. Then at the line 45
>> Create_Code_SIL overwrites that object with another instance with no
>> name set. When you try to get its name, the handle of the string is
>> invalid. An attempt to get the value of gives Constraint_Error.
>>
>> P.S. If you want to set components individually you must either expose
>>
>> them or else provide setters.
>>
>> --
>> Regards,
>> Dmitry A. Kazakov
>> http://www.dmitry-kazakov.de
>>
> Then why didn't it fail immediately on the first run? Antibiotics is a
> record with 4 of those lazy Safe String objects.
>
> Name/=Code_SIL/=CMI/=SIR
>
> Each one has its own Create/Value function.

Your Create function creates a whole object.

> Wasn't sure/ had expected (big mistake as always) that I could somehow
> use the Create/Value functions from Safe String without having to write
> additional code.

Of course you can. But Object you create is not a Safe_String object.

> The test was actually to figure out how it would work and if it would
> make a difference compared with the Unbounded_Strings package and with
> the old version.

If you used Unbounded_String, Name would become empty after you 
overwrote the object. The same behavior with Safe_String is easy to 
achieve. In Base_Types.Antibiotics replace Name_Value with this

    function Name_Value (Item : Object) return String is
    begin
       if Item.Name.Is_Valid then
          return Item.Name.Value;
       else
          return "";
       end if;
    end Name_Value;

(Here Ada 2005 prefix notation is used, which is much clearer)

Now, there is no Constraint_Error and the result is empty string.

> I am quite tempted in using the persistent storage capabilities of
> Simple Components but that means that I have to adapt my program to the
> style of this library. Don't think that it would be possible to only graft it
> at the latest moment?

It is not style, but a plain conceptual error. You are using a 
constructing function as if it were a setter. That won't work anywhere 
in any language.

Replace

    Create_Name (Name : String) return Object;
    Create_Code_SIL (Name : String) return Object;
    ...

with

    Set_Name (Data : in out Object; Name : String);
    Set_Code_SIL (Data : in out Object; Name : String);
    ...

> BTW what is the reach of the overriding keyword i.e.:

The keyword hints the compiler that the subprogram overrides the 
parent's implementation. If you make a mistake in the parameter profile, 
the compiler will reject the program. It adds a lot of safety. If not 
keeping it Ada 95 compatible, always use "overriding" and "not 
overriding" when declaring operations on tagged types. It is a good style.

> Gnat was only complaining that Create_Name needs overriding even if
> Create_Code_SIL is also in the Base_Type which is abstract.

This a different story. Here the compiler complains that you forgot to 
override an operation that must be overridden. Overriding is required 
for abstract operations and operations returning new objects. In the 
first case there is no implementation to inherit from. In  the second 
case the implementation would be most likely garbage.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

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

* Re: Experimenting with the OOP features in Ada
       [not found]     ` <85ef59f3-bcbe-4630-9b4d-8285623ab456@googlegroups.com>
@ 2017-01-03 12:48       ` Brian Drummond
  2017-01-03 13:43         ` Laurent
  0 siblings, 1 reply; 24+ messages in thread
From: Brian Drummond @ 2017-01-03 12:48 UTC (permalink / raw)


On Mon, 02 Jan 2017 08:05:18 -0800, Laurent wrote:

> On Monday, 2 January 2017 15:44:57 UTC+1, Brian Drummond  wrote:

>> Test_Antibiotic := Base_Types.Antibiotics.Create_Code_SIL (
>>                              This => Test_Antibiotic, Code_SIL => "Test
>>                              Antibiotic 3")
>> 
>> Test_Antibiotic := Test_Antibiotic.Create_Code_SIL
>>                             (Code_SIL => "Test Antibiotic 3");
>> 
>> but the preferred form would be
>> 
>> Test_Antibiotic.Set_Code_SIL (Code_SIL => "gen");
>> 
>> -- Brian
> 
> Probably your versions does what I couldn't figure out. I declared Item
> inside the function not as parameter.
> But would that cause a constraint error?

If you try to access "Name" of an object that was created without a 
"Name", yes it would. 

I didn't dig deep enough into your constructors to see if that was 
genuinely the case or if they were created with some default, but the 
constraint error was clear enough evidence for me. I find Ada very good 
at catching mistakes early instead of burying them in non-obvious 
behaviour.

-- Brian

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

* Re: Experimenting with the OOP features in Ada
  2017-01-02 16:27     ` Laurent
@ 2017-01-03 13:01       ` Brian Drummond
  2017-01-03 13:57         ` Laurent
  0 siblings, 1 reply; 24+ messages in thread
From: Brian Drummond @ 2017-01-03 13:01 UTC (permalink / raw)


On Mon, 02 Jan 2017 08:27:44 -0800, Laurent wrote:

> On Monday, 2 January 2017 15:44:57 UTC+1, Brian Drummond  wrote:
>> So the
>> following are equivalent:
>> 
>> Test_Antibiotic := Base_Types.Antibiotics.Create_Code_SIL (
>>                              This => Test_Antibiotic, Code_SIL => "Test
>>                              Antibiotic 3")
>> 
>> Test_Antibiotic := Test_Antibiotic.Create_Code_SIL
>>                             (Code_SIL => "Test Antibiotic 3");
>> 
>> but the preferred form would be
>> 
>> Test_Antibiotic.Set_Code_SIL (Code_SIL => "gen");
>> 
>> -- Brian
> 
> Yes last one looks nice but doesn't work. No selector... Object is
> private.
> So 2nd one.
> Now I won't compile because Base_Types.Object is abstract. So I have to
> figure out how/where to put the overriding works. In John Barnes Book it
> looks so easy and light. Doing it myself feels clumsy


I recommend learning how to make the nicest looking one work; my 
procedure was a first pass at guidance, not a complete solution.

Procedure Set_Code_SIL (This : in out Base_Types.Antibiotics.Objects;
                        Code_SIL => "gen");

Where did you put this procedure?

As Dmitry says, you need to provide setters if you're manipulating parts 
of an object, so this procedure, a setter, should be part of the 
Base_Types.Antibiotics package (with implementation in its body) so that 
it has access to the private part, where the components are declared.

The error message fragment (without file:location) you report suggests it 
was probably somewhere else.

-- Brian


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

* Re: Experimenting with the OOP features in Ada
  2017-01-02 20:55     ` Dmitry A. Kazakov
@ 2017-01-03 13:39       ` Laurent
  2017-01-03 14:40         ` Dmitry A. Kazakov
  0 siblings, 1 reply; 24+ messages in thread
From: Laurent @ 2017-01-03 13:39 UTC (permalink / raw)


On Monday, 2 January 2017 21:55:49 UTC+1, Dmitry A. Kazakov  wrote:

> Your Create function creates a whole object.
> 
Ok my fault. Transformed the into procedures and changed the name.

> > I am quite tempted in using the persistent storage capabilities of
> > Simple Components but that means that I have to adapt my program to the
> > style of this library. Don't think that it would be possible to only graft
> > it
> > at the latest moment?
> > > 
> It is not style, but a plain conceptual error. You are using a 
> constructing function as if it were a setter. That won't work anywhere 
> in any language.
> 
Wasn't what I tried to say. In the docs about persistent objects you write:
"Like other objects, persistent ones are normally accessed through handles."

The old version of my program doesn't contain handles. No access values or
whatever.
So I have actually to rewrite it completely from the beginning and adapt it to
Simple Components.

> > BTW what is the reach of the overriding keyword i.e.:
> > > 
> The keyword hints the compiler that the subprogram overrides the 
> parent's implementation. If you make a mistake in the parameter profile, 
> the compiler will reject the program. It adds a lot of safety. If not 
> keeping it Ada 95 compatible, always use "overriding" and "not 
> overriding" when declaring operations on tagged types. It is a good style.
> 
> 
But I have to put it for every function/procedure.
It won't work if I just put it at the first possible place and expect that the
compiler will automagically figure out where to apply it.

> > Gnat was only complaining that Create_Name needs overriding even if
> > Create_Code_SIL is also in the Base_Type which is abstract.
> > > 
> This a different story. Here the compiler complains that you forgot to 
> override an operation that must be overridden. Overriding is required 
> for abstract operations and operations returning new objects. In the 
> first case there is no implementation to inherit from. In  the second 
> case the implementation would be most likely garbage.
> 
> 
After changing the functions to procedures gnat complains that Set_Code_SIL
doesn't override. Before the change it didn't even it should have done so?
> -- 
> Regards,
> Dmitry A. Kazakov
> http://www.dmitry-kazakov.de
> 

Thanks


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

* Re: Experimenting with the OOP features in Ada
  2017-01-03 12:48       ` Brian Drummond
@ 2017-01-03 13:43         ` Laurent
  0 siblings, 0 replies; 24+ messages in thread
From: Laurent @ 2017-01-03 13:43 UTC (permalink / raw)


On Tuesday, 3 January 2017 13:49:53 UTC+1, Brian Drummond  wrote:
> On Mon, 02 Jan 2017 08:05:18 -0800, Laurent wrote:
> 
> > On Monday, 2 January 2017 15:44:57 UTC+1, Brian Drummond  wrote:
> > > 
> >> Test_Antibiotic := Base_Types.Antibiotics.Create_Code_SIL (
> >>                              This => Test_Antibiotic, Code_SIL => "Test
> >>                              Antibiotic 3")
> >> 
> >> Test_Antibiotic := Test_Antibiotic.Create_Code_SIL
> >>                             (Code_SIL => "Test Antibiotic 3");
> >> 
> >> but the preferred form would be
> >> 
> >> Test_Antibiotic.Set_Code_SIL (Code_SIL => "gen");
> >> 
> >> -- Brian
> >> > > 
> > Probably your versions does what I couldn't figure out. I declared Item
> > inside the function not as parameter.
> > But would that cause a constraint error?
> > > 
> If you try to access "Name" of an object that was created without a 
> "Name", yes it would. 
> 
> I didn't dig deep enough into your constructors to see if that was 
> genuinely the case or if they were created with some default, but the 
> constraint error was clear enough evidence for me. I find Ada very good 
> at catching mistakes early instead of burying them in non-obvious 
> behaviour.
> 
> -- Brian
> 
Yes transforming the functions to procedure solved this. No more constructors
for the components. Just one for the Object itself.

Thanks

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

* Re: Experimenting with the OOP features in Ada
  2017-01-03 13:01       ` Brian Drummond
@ 2017-01-03 13:57         ` Laurent
  2017-01-03 14:31           ` Dmitry A. Kazakov
  0 siblings, 1 reply; 24+ messages in thread
From: Laurent @ 2017-01-03 13:57 UTC (permalink / raw)


On Tuesday, 3 January 2017 14:02:56 UTC+1, Brian Drummond  wrote:

> I recommend learning how to make the nicest looking one work; my 
> procedure was a first pass at guidance, not a complete solution.
> 
> 
That would feel like cheating. Makes a lot fun to try to figure out how things
work.

> Procedure Set_Code_SIL (This : in out Base_Types.Antibiotics.Objects;
>                         Code_SIL => "gen");
> 
> Where did you put this procedure?
> 
> As Dmitry says, you need to provide setters if you're manipulating parts 
> of an object, so this procedure, a setter, should be part of the 
> Base_Types.Antibiotics package (with implementation in its body) so that 
> it has access to the private part, where the components are declared.
> 
> The error message fragment (without file:location) you report suggests it 
> was probably somewhere else.
> 
> -- Brian
> 
After some sleep and a clean up of the code, everything is much clearer now.

The only thing which I am not able to see is if I can transform this into a
procedure and how I would do it. The Ptr confuses me because I don't
understand where it should point to in a procedure.

   function Create (Value : String) return My_Safe_String
   is
      Ptr : My_String_Ptr := new My_String (Value'Length);
   begin
      Ptr.Value := Value;
      return Ref (Ptr);
   end Create;
   

Item.Name.Set (Name=>"Something") looks better than 

Item.Name := My_Strings.Handle.Create (Value => Name);

Thanks

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

* Re: Experimenting with the OOP features in Ada
  2017-01-03 13:57         ` Laurent
@ 2017-01-03 14:31           ` Dmitry A. Kazakov
  2017-01-03 17:07             ` G.B.
  2017-01-04 12:18             ` Laurent
  0 siblings, 2 replies; 24+ messages in thread
From: Dmitry A. Kazakov @ 2017-01-03 14:31 UTC (permalink / raw)


On 2017-01-03 14:57, Laurent wrote:

> The only thing which I am not able to see is if I can transform this into a
> procedure and how I would do it. The Ptr confuses me because I don't
> understand where it should point to in a procedure.
>
>    function Create (Value : String) return My_Safe_String
>    is
>       Ptr : My_String_Ptr := new My_String (Value'Length);
>    begin
>       Ptr.Value := Value;
>       return Ref (Ptr);
>    end Create;

In the sample code this procedure is called Copy. Regarding using 
in-place notation that would be:

    Value.Set (new My_String'(Object.Entity with Value'Length, Value));

> Item.Name.Set (Name=>"Something") looks better than
>
> Item.Name := My_Strings.Handle.Create (Value => Name);

Some people like using unary "+" for this. E.g.

    function "+" (Value : String) return My_Safe_String
       renames My_Strings.Handle.Create;

Then you can do:

    Item.Name := +"Something";

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

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

* Re: Experimenting with the OOP features in Ada
  2017-01-03 13:39       ` Laurent
@ 2017-01-03 14:40         ` Dmitry A. Kazakov
  0 siblings, 0 replies; 24+ messages in thread
From: Dmitry A. Kazakov @ 2017-01-03 14:40 UTC (permalink / raw)


On 2017-01-03 14:39, Laurent wrote:
> On Monday, 2 January 2017 21:55:49 UTC+1, Dmitry A. Kazakov  wrote:

>> The keyword hints the compiler that the subprogram overrides the
>> parent's implementation. If you make a mistake in the parameter profile,
>> the compiler will reject the program. It adds a lot of safety. If not
>> keeping it Ada 95 compatible, always use "overriding" and "not
>> overriding" when declaring operations on tagged types. It is a good style.
>>
> But I have to put it for every function/procedure.
> It won't work if I just put it at the first possible place and expect that the
> compiler will automagically figure out where to apply it.

That is the idea. The compiler already knows if that is overriding or 
not. You tell it that your intention was to override. It is a fully 
redundant declaration meant to add safety.

To put it in other words, if your program compiles you could remove all 
appearances of "overriding" and "not overriding" and it would still 
compile. [The reverse is wrong, as your attempt below illustrated]

>>> Gnat was only complaining that Create_Name needs overriding even if
>>> Create_Code_SIL is also in the Base_Type which is abstract.
>>>>
>> This a different story. Here the compiler complains that you forgot to
>> override an operation that must be overridden. Overriding is required
>> for abstract operations and operations returning new objects. In the
>> first case there is no implementation to inherit from. In  the second
>> case the implementation would be most likely garbage.
>>
>>
> After changing the functions to procedures gnat complains that Set_Code_SIL
> doesn't override. Before the change it didn't even it should have done so?

Because it is not overriding. Then you declare it as "not overriding". 
Always tell the compiler the truth. (:-))

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

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

* Re: Experimenting with the OOP features in Ada
  2017-01-03 14:31           ` Dmitry A. Kazakov
@ 2017-01-03 17:07             ` G.B.
  2017-01-03 20:42               ` Dmitry A. Kazakov
  2017-01-04 12:18             ` Laurent
  1 sibling, 1 reply; 24+ messages in thread
From: G.B. @ 2017-01-03 17:07 UTC (permalink / raw)


On 03/01/2017 15:31, Dmitry A. Kazakov wrote:
> On 2017-01-03 14:57, Laurent wrote:

>> Item.Name.Set (Name=>"Something") looks better than
>>
>> Item.Name := My_Strings.Handle.Create (Value => Name);
>
> Some people like using unary "+" for this. E.g.
>
>    function "+" (Value : String) return My_Safe_String
>       renames My_Strings.Handle.Create;
>
> Then you can do:
>
>    Item.Name := +"Something";

Using an operator seems always a good idea when the language
does not otherwise support a ubiquitous notion such as a handle.

Otherwise, both the domain data types and data handling
types are indistinguishable, language-wise, and the reader
is left in daze: is this program text about handles or is
it about data?


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

* Re: Experimenting with the OOP features in Ada
  2017-01-03 17:07             ` G.B.
@ 2017-01-03 20:42               ` Dmitry A. Kazakov
  0 siblings, 0 replies; 24+ messages in thread
From: Dmitry A. Kazakov @ 2017-01-03 20:42 UTC (permalink / raw)


On 2017-01-03 18:07, G.B. wrote:
> On 03/01/2017 15:31, Dmitry A. Kazakov wrote:
>> On 2017-01-03 14:57, Laurent wrote:
>
>>> Item.Name.Set (Name=>"Something") looks better than
>>>
>>> Item.Name := My_Strings.Handle.Create (Value => Name);
>>
>> Some people like using unary "+" for this. E.g.
>>
>>    function "+" (Value : String) return My_Safe_String
>>       renames My_Strings.Handle.Create;
>>
>> Then you can do:
>>
>>    Item.Name := +"Something";
>
> Using an operator seems always a good idea when the language
> does not otherwise support a ubiquitous notion such as a handle.

Nope, the good idea is to fix the language.

> Otherwise, both the domain data types and data handling
> types are indistinguishable, language-wise, and the reader
> is left in daze: is this program text about handles or is
> it about data?

No problem. When you write 1 is it Positive, Integer, mod 4? The reader 
easily determines that from the context as the compiler does. In rare 
cases when it cannot be determined, a qualified expression does the job.

Ada should have supported subtypes we discussed before. The ones that do 
not share the representation but only the interface. Then both String 
and a handle to a String could be subtypes of each other and you could 
assign one to another (which would invoke a user-defined conversion). 
That would also resolve the mess of standard Ada string types.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

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

* Re: Experimenting with the OOP features in Ada
  2017-01-03 14:31           ` Dmitry A. Kazakov
  2017-01-03 17:07             ` G.B.
@ 2017-01-04 12:18             ` Laurent
  2017-01-04 12:44               ` Dmitry A. Kazakov
  2017-01-04 15:09               ` Shark8
  1 sibling, 2 replies; 24+ messages in thread
From: Laurent @ 2017-01-04 12:18 UTC (permalink / raw)


On Tuesday, 3 January 2017 15:31:16 UTC+1, Dmitry A. Kazakov  wrote:
> On 2017-01-03 14:57, Laurent wrote:
> 
> > The only thing which I am not able to see is if I can transform this into a
> > procedure and how I would do it. The Ptr confuses me because I don't
> > understand where it should point to in a procedure.
> > > > > > > >
> >    function Create (Value : String) return My_Safe_String
> >    is
> >       Ptr : My_String_Ptr := new My_String (Value'Length);
> >    begin
> >       Ptr.Value := Value;
> >       return Ref (Ptr);
> >    end Create;
> > > > > > > 
> In the sample code this procedure is called Copy. Regarding using 
> in-place notation that would be:
> 
>     Value.Set (new My_String'(Object.Entity with Value'Length, Value));
> 
> > Item.Name.Set (Name=>"Something") looks better than
> > > > > > > >
> > Item.Name := My_Strings.Handle.Create (Value => Name);
> > > > > > > 
> Some people like using unary "+" for this. E.g.
> 
>     function "+" (Value : String) return My_Safe_String
>        renames My_Strings.Handle.Create;
> 
> Then you can do:
> 
>     Item.Name := +"Something";
> 
> -- 
> Regards,
> Dmitry A. Kazakov
> http://www.dmitry-kazakov.de
> 
> > > 
The solution with the unary "+" sounds familiar. Forgot only that it was
possible.
Looks less complicate than the other solution.

Other thing I don't understand:

For the persistent storage solution I need those handles. So I tried to adapt
the Base_Types package by copying the Safe_Strings example.

with My_Strings;
with My_Strings.Handle;
with Object;

package Base_Types is

   type Object is abstract new Object.Entity with private;
   
   subtype Name_Type is My_Strings.Handle.My_Safe_String;
   subtype Code_SIL_Type is My_Strings.Handle.My_Safe_String;

   procedure Set_Name (Item : in out Object; Name : String) is abstract;
   procedure Set_Code_SIL (Item : in out Object; Code_SIL : String) is abstract;

   function Name_Value (Item : Object) return String is abstract;
   function Code_SIL_Value (Item : Object) return String is abstract;

private

   type Object 
   is abstract new Object.Entity with
      record
         Name     : Name_Type;
         Code_SIL : Code_SIL_Type;
      end record;
   
   type Base_Type_Ptr is access Object'Class;

end Base_Types;

There seems to be no place where I can insert an tagged keyword? Is that
possible or do I have to do it differently?

When I compile this I get a few errors:

and some more of the following but they are just a symptom not the cause:

test.adb:16:23: invalid prefix in selected component "Test_Antibiotic"
test.adb:16:38: prefixed call is only allowed for objects of a tagged type

base_types.ads:7:32: object "Object" cannot be used before end of its
declaration
base_types.ads:22:20: type "Object" cannot be used before end of its declaration
base_types.ads:28:33: tagged type required, found type "Object" defined at line
21

base_types-antibiotics.ads:12:4: subprogram "Name_Value" is not overriding

Thanks

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

* Re: Experimenting with the OOP features in Ada
  2017-01-04 12:18             ` Laurent
@ 2017-01-04 12:44               ` Dmitry A. Kazakov
  2017-01-05 11:41                 ` Laurent
  2017-01-04 15:09               ` Shark8
  1 sibling, 1 reply; 24+ messages in thread
From: Dmitry A. Kazakov @ 2017-01-04 12:44 UTC (permalink / raw)


On 2017-01-04 13:18, Laurent wrote:

> Other thing I don't understand:
>
> For the persistent storage solution I need those handles.

Actually the base type for persistent objects is 
Object.Archived.Deposit. Object.Entity is merely a reference-counted 
object. Object.Archived.Deposit is that plus operations to 
serialize/deserialize and handle inter-object dependencies/references.

> So I tried to adapt
> the Base_Types package by copying the Safe_Strings example.
>
> with My_Strings;
> with My_Strings.Handle;
> with Object;
>
> package Base_Types is
>
>    type Object is abstract new Object.Entity with private;
>
>    subtype Name_Type is My_Strings.Handle.My_Safe_String;
>    subtype Code_SIL_Type is My_Strings.Handle.My_Safe_String;
>
>    procedure Set_Name (Item : in out Object; Name : String) is abstract;
>    procedure Set_Code_SIL (Item : in out Object; Code_SIL : String) is abstract;
>
>    function Name_Value (Item : Object) return String is abstract;
>    function Code_SIL_Value (Item : Object) return String is abstract;
>
> private
>
>    type Object
>    is abstract new Object.Entity with
>       record
>          Name     : Name_Type;
>          Code_SIL : Code_SIL_Type;
>       end record;

If you are not going to change string components you could simply do

   type Object (Name_Length : Positive; Code_SIL_Length : Positive) is
      abstract new Object.Entity with
   record
      Name     : String (1..Name_Length);
      Code_SIL : String (1..Code_SIL_Length);
   end record;

>    type Base_Type_Ptr is access Object'Class;
>
> end Base_Types;
>
> There seems to be no place where I can insert an tagged keyword?

Object.Entity and Object.Archived.Deposit are already tagged.

> When I compile this I get a few errors:
>
> and some more of the following but they are just a symptom not the cause:
>
> test.adb:16:23: invalid prefix in selected component "Test_Antibiotic"
> test.adb:16:38: prefixed call is only allowed for objects of a tagged type
>
> base_types.ads:7:32: object "Object" cannot be used before end of its
> declaration
> base_types.ads:22:20: type "Object" cannot be used before end of its declaration
> base_types.ads:28:33: tagged type required, found type "Object" defined at line
> 21

The package name Object gets hidden by the declaration the type Object. 
Change it to:

   type Object is abstract new Standard.Object.Entity ...

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

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

* Re: Experimenting with the OOP features in Ada
  2017-01-04 12:18             ` Laurent
  2017-01-04 12:44               ` Dmitry A. Kazakov
@ 2017-01-04 15:09               ` Shark8
  2017-01-05 11:54                 ` Laurent
  1 sibling, 1 reply; 24+ messages in thread
From: Shark8 @ 2017-01-04 15:09 UTC (permalink / raw)


On Wednesday, January 4, 2017 at 5:18:42 AM UTC-7, Laurent wrote:
> 
> with My_Strings;
> with My_Strings.Handle;
> with Object;
> 
> package Base_Types is
> 
>    type Object is abstract new Object.Entity with private;
>    
>    subtype Name_Type is My_Strings.Handle.My_Safe_String;
>    subtype Code_SIL_Type is My_Strings.Handle.My_Safe_String;
> 
>    procedure Set_Name (Item : in out Object; Name : String) is abstract;
>    procedure Set_Code_SIL (Item : in out Object; Code_SIL : String) is abstract;
> 
>    function Name_Value (Item : Object) return String is abstract;
>    function Code_SIL_Value (Item : Object) return String is abstract;
> 
> private
> 
>    type Object 
>    is abstract new Object.Entity with
>       record
>          Name     : Name_Type;
>          Code_SIL : Code_SIL_Type;
>       end record;
>    
>    type Base_Type_Ptr is access Object'Class;
> 
> end Base_Types;
> 
> There seems to be no place where I can insert an tagged keyword? Is that
> possible or do I have to do it differently?
> 
> When I compile this I get a few errors:
> 
> and some more of the following but they are just a symptom not the cause:
> 
> test.adb:16:23: invalid prefix in selected component "Test_Antibiotic"
> test.adb:16:38: prefixed call is only allowed for objects of a tagged type
> 
> base_types.ads:7:32: object "Object" cannot be used before end of its
> declaration
> base_types.ads:22:20: type "Object" cannot be used before end of its declaration
> base_types.ads:28:33: tagged type required, found type "Object" defined at line
> 21

You're misunderstanding the errors -- they aren't about the keyword 'Tagged', they're about the declaration itself.

When you have "Type object [...]" everything after that hides package Object you're withing. (Hence the compiler saying "type 'Object' cannot be used before end of its declaration".) -- The solution is to _immediately_ after "package Base_Types is" insert a line renaming package Object and then prefix type object's derivation-definition with the rename.

Example:

    With Object;
    package Base_Types is
      Package Obj_Rename renames Object;
      
      type Object is abstract new Obj_Rename.Object.Entity with private;


That will take care of that error.


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

* Re: Experimenting with the OOP features in Ada
  2017-01-04 12:44               ` Dmitry A. Kazakov
@ 2017-01-05 11:41                 ` Laurent
  2017-01-05 13:02                   ` Dmitry A. Kazakov
  2017-01-05 13:11                   ` AdaMagica
  0 siblings, 2 replies; 24+ messages in thread
From: Laurent @ 2017-01-05 11:41 UTC (permalink / raw)


On Wednesday, 4 January 2017 13:44:31 UTC+1, Dmitry A. Kazakov  wrote:
> On 2017-01-04 13:18, Laurent wrote:
> 
> > Other thing I don't understand:
> > > > > >
> > For the persistent storage solution I need those handles.
> > > > > 
> Actually the base type for persistent objects is 
> Object.Archived.Deposit. Object.Entity is merely a reference-counted 
> object. Object.Archived.Deposit is that plus operations to 
> serialize/deserialize and handle inter-object dependencies/references.
> 
> > 
Ok. Until now I didn't read any further than the Safe_String example, so I
copied its structure.

> 
> If you are not going to change string components you could simply do
> 
>    type Object (Name_Length : Positive; Code_SIL_Length : Positive) is
>       abstract new Object.Entity with
>    record
>       Name     : String (1..Name_Length);
>       Code_SIL : String (1..Code_SIL_Length);
>    end record;
> 
> >    type Base_Type_Ptr is access Object'Class;
> > > > > >
> > end Base_Types;
> > > > > >
> > > > > >> > > >
I think I leave it for the moment as it is. 

> > There seems to be no place where I can insert an tagged keyword?
> > > > > 
> Object.Entity and Object.Archived.Deposit are already tagged.
> 
> > 
And that is why there is no place to put it? Or does abstract automatically
implies tagged?

> The package name Object gets hidden by the declaration the type Object. 
> Change it to:
> 
>    type Object is abstract new Standard.Object.Entity ...
> 
Why Standard? Thought that was for libraries which come preinstalled? I thought I
get access to Simple Components via Gnoga?

So previous errors are gone, a new one:

base_types-antibiotics.ads:30:9: type must be declared abstract or "Get_Class"
overridden

So I looked at Get_Class. 

-- Get_Class -- Of an object
--
--    Object - The object
--
-- This  function  returns  the  class  of Object. The class is a string
-- uniquely  describing  the  object's type. It is analogous to external
-- type  tag representation. Though, different types of objects may have
-- same class if necessary.
--
-- Returns :
--
--    The object class
--
   function Get_Class (Object : Deposit) return String is abstract;

Hm is abstract, so no body to copy from. What is it doing? 
If Object is of type ie.: Base_Type it will return a String with Base_Type?

Thanks

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

* Re: Experimenting with the OOP features in Ada
  2017-01-04 15:09               ` Shark8
@ 2017-01-05 11:54                 ` Laurent
  0 siblings, 0 replies; 24+ messages in thread
From: Laurent @ 2017-01-05 11:54 UTC (permalink / raw)


On Wednesday, 4 January 2017 16:09:48 UTC+1, Shark8  wrote:

> You're misunderstanding the errors -- they aren't about the keyword 'Tagged',
> they're about the declaration itself.
> 
> When you have "Type object [...]" everything after that hides package Object
> you're withing. (Hence the compiler saying "type 'Object' cannot be used
> before end of its declaration".) -- The solution is to _immediately_ after
> "package Base_Types is" insert a line renaming package Object and then prefix
> type object's derivation-definition with the rename.
> 
> Example:
> 
>     With Object;
>     package Base_Types is
>       Package Obj_Rename renames Object;
>       
>       type Object is abstract new Obj_Rename.Object.Entity with private;
> 
> > > > 
> That will take care of that error.
> 
> 
Both proposed solutions work. Can't decide which one to choose.

Hm yes had a fixation on the the tagged keyword. For a moment I was tempted to
change the name of the type but couldn't find anything better than Object and
abandoned. Instead of putting something else only to see if it makes a difference.

Shouldn't the compiler then complain that there are 2 entities with the same
name? Or a least give a warning that this could cause problems?

Thanks

Ps: does someone know of an language addon for BBEdit?


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

* Re: Experimenting with the OOP features in Ada
  2017-01-05 11:41                 ` Laurent
@ 2017-01-05 13:02                   ` Dmitry A. Kazakov
  2017-01-05 13:11                   ` AdaMagica
  1 sibling, 0 replies; 24+ messages in thread
From: Dmitry A. Kazakov @ 2017-01-05 13:02 UTC (permalink / raw)


On 2017-01-05 12:41, Laurent wrote:
> On Wednesday, 4 January 2017 13:44:31 UTC+1, Dmitry A. Kazakov  wrote:

>> Object.Entity and Object.Archived.Deposit are already tagged.
>>
>>>
> And that is why there is no place to put it? Or does abstract automatically
> implies tagged?

No.

Object.Entity is derived from Ada.Finalization.Limited_Controlled which 
is tagged.

[Tagged property is transitive upon derivation.]

>> The package name Object gets hidden by the declaration the type Object.
>> Change it to:
>>
>>    type Object is abstract new Standard.Object.Entity ...
>>
> Why Standard? Thought that was for libraries which come preinstalled? I thought I
> get access to Simple Components via Gnoga?

Standard is the root package in Ada. So the full name of the package 
Object is Standard.Object.

> So previous errors are gone, a new one:
>
> base_types-antibiotics.ads:30:9: type must be declared abstract or "Get_Class"
> overridden
>
> So I looked at Get_Class.
>
> -- Get_Class -- Of an object
> --
> --    Object - The object
> --
> -- This  function  returns  the  class  of Object. The class is a string
> -- uniquely  describing  the  object's type. It is analogous to external
> -- type  tag representation. Though, different types of objects may have
> -- same class if necessary.
> --
> -- Returns :
> --
> --    The object class
> --
>    function Get_Class (Object : Deposit) return String is abstract;
>
> Hm is abstract, so no body to copy from. What is it doing?

A persistent object must be stored externally. When you restore it you 
must know its Ada type. The string returned by Get_Class is the 
information you will use to get at that type.

> If Object is of type ie.: Base_Type it will return a String with Base_Type?

It is any text. See 2.4 and 2.4.2 for sample code. 2.4.2 implements a 
persistent binary tree of nodes. Each tree node is a separate persistent 
object.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


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

* Re: Experimenting with the OOP features in Ada
  2017-01-05 11:41                 ` Laurent
  2017-01-05 13:02                   ` Dmitry A. Kazakov
@ 2017-01-05 13:11                   ` AdaMagica
  1 sibling, 0 replies; 24+ messages in thread
From: AdaMagica @ 2017-01-05 13:11 UTC (permalink / raw)


Am Donnerstag, 5. Januar 2017 12:41:12 UTC+1 schrieb Laurent:
> On Wednesday, 4 January 2017 13:44:31 UTC+1, Dmitry A. Kazakov  wrote:
> > The package name Object gets hidden by the declaration the type Object.
> > Change it to:
> >
> >    type Object is abstract new Standard.Object.Entity ...
> >
> Why Standard? Thought that was for libraries which come preinstalled?

Each declaration gets a name, called Direct_Name, and this name hides any homographs that are directly visible at that place.

So here
type Object -- this hides Object mentioned in the with clause
is abstract new Standard.Object  -- this qualification makes is visible again
.Entity

Why Standard?
The name of any declaration in Ada can be expanded in the following way:

function F return T is
  I: Integer;

I is declared locally within F, thus the expanded name is F.I.
Now F itself is declared within some declarative region, say a package, a subprogram, a named declare block, call it D => The expanded name is D.F.I.

Now any declaration on library level (a package or subprogram) is conceptually declared within package Standard.

So if D is on libray level, the fully expanded name is Standard.D.F.I.

Hope you now see why Standard.

PS: This fully expanded name does not grant visibility from outside into F.


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

end of thread, other threads:[~2017-01-05 13:11 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-02 13:21 Experimenting with the OOP features in Ada Laurent
2017-01-02 14:11 ` Brian Drummond
2017-01-02 14:43   ` Brian Drummond
2017-01-02 16:27     ` Laurent
2017-01-03 13:01       ` Brian Drummond
2017-01-03 13:57         ` Laurent
2017-01-03 14:31           ` Dmitry A. Kazakov
2017-01-03 17:07             ` G.B.
2017-01-03 20:42               ` Dmitry A. Kazakov
2017-01-04 12:18             ` Laurent
2017-01-04 12:44               ` Dmitry A. Kazakov
2017-01-05 11:41                 ` Laurent
2017-01-05 13:02                   ` Dmitry A. Kazakov
2017-01-05 13:11                   ` AdaMagica
2017-01-04 15:09               ` Shark8
2017-01-05 11:54                 ` Laurent
     [not found]     ` <85ef59f3-bcbe-4630-9b4d-8285623ab456@googlegroups.com>
2017-01-03 12:48       ` Brian Drummond
2017-01-03 13:43         ` Laurent
2017-01-02 15:54   ` Laurent
2017-01-02 16:41 ` Dmitry A. Kazakov
2017-01-02 18:50   ` Laurent
2017-01-02 20:55     ` Dmitry A. Kazakov
2017-01-03 13:39       ` Laurent
2017-01-03 14:40         ` Dmitry A. Kazakov

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