comp.lang.ada
 help / color / mirror / Atom feed
From: Victor Porton <porton@narod.ru>
Subject: Re: A bad counterintuitive behaviour of Ada about OO
Date: Wed, 06 Aug 2014 01:13:56 +0300
Date: 2014-08-06T01:13:56+03:00	[thread overview]
Message-ID: <lrrkv5$fke$1@speranza.aioe.org> (raw)
In-Reply-To: c4d1ujFghdnU1@mid.individual.net

Niklas Holsti wrote:

> On 14-08-06 00:06 , Victor Porton wrote:
>> Simon Wright wrote:
>> 
>>> Victor Porton <porton@narod.ru> writes:
>>>
>>>> http://freesoft.portonvictor.org/binaries/ada-obj-test.tar.gz
>>>>
>>>> contains a tiny Ada program which prints 0 despite intuition suggests
>>>> that it should print 123, because it just copies (using Adjust) an
>>>> object holding 123.
>>>>
>>>> In this program Handle_Type models some handle provided by an external
>>>> API, where 0 is an undefined handle. Base_Object is a tagged record
>>>> which holds a handle inside itself and can copy or destroy the handle
>>>> automatically (as Base_Object is a controlled object).
>>>>
>>>> Example_Record is a derived type of Base_Object which imitates a
>>>> behavior of a simple library which operates over some handles. For
>>>> example, in this example copying a handle preserves it unchanged.
>>>>
>>>> This tiny program was created by me as a model of my real Ada bindings
>>>> for Raptor C library, which produces a wrong behavior.
>>>>
>>>> Why Ada behaves in this counter-intuitive way?
>>>>
>>>> What should I do in similar situations when developing real Ada
>>>> software?
>>>
>>> I think what is happening is that in
>>>
>>>    function From_Handle(Handle: Handle_Type) return Base_Object is
>>>    begin
>>>       return (Ada.Finalization.Controlled with Handle=>Handle);
>>>    end;
>>>
>>> the aggregate is created and copied to the function's result as a
>>> Base_Object, so that when
>>>
>>>    procedure Adjust(Object: in out Base_Object) is
>>>    begin
>>>       if Object.Handle /= 0 then
>>>          Object.Handle := Copy_Handle(Base_Object'Class(Object),
>>>          Object.Handle);
>>>       end if;
>>>    end;
>>>
>>> is called during the copy,
>>>
>>>    function Copy_Handle(Object: Base_Object; Handle: Handle_Type) return
>>>    Handle_Type is begin
>>>       return 0;
>>>    end;
>>>
>>> returns 0, as you've seen.
>>>
>>>
>>> (1) If all you wanted to do was copy the Handle over, you don't need to
>>> do anything, because that's the default behaviour (i.e., copies the
>>> bits).
>>>
>>> (2) Normally, From_Handle wouldn't be inherited, so you'd have had to
>>> write your own; because Example_Object has a null extension, it can be
>>> inherited.
>> 
>> I've added in example_record.ads:
>> 
>>    function From_Handle(Handle: Handle_Type) return Example_Object;
>> 
>> and in example_record.adb:
>> 
>>    function From_Handle(Handle: Handle_Type) return Example_Object is
>>    begin
>>       return (Base_Object'(From_Handle(Handle)) with null record);
>>    end;
>> 
>> It prints "0" not as it was before.
> 
> (I assume the "not" above is a mistake, and you mean that it prints "0"
> just as before.)

Yes, my typo.

> That happens because in your new From_Handle for Example_Object, the
> part Base_Object'(From_Handle(Handle)) returns an object of type
> Base_Object, which is then assigned into the parent part of the
> extension aggregate, and this assignment operation invokes the Adjust
> operation for Base_Object, which invokes Copy_Handle for Base_Object,
> which returns a zero handle.
> 
>> What to do? I write a real software project and need to make a decision
>> what to do in this situation.
> 
> Alternatives:
> 
> 1. Write a sensible Copy_Handle for Base_Object (preferred solution), or

It is hardly possible to make sensible Copy_Handle for Base_Object, because 
the copy handler is different for every kind of objects.

> 2. make Example_Record a child package of Handled_Record, which makes
> the internal structure of Base_Object visible, and lets you write
> 
>     function From_Handle(Handle: Handle_Type) return Example_Object is
>     begin
>        return (Ada.Finalization.Controlled with Handle => Handle);
>     end;
> 
> and therefore lets you create Example_Objects without going through a
> Base_Object and its handle-destroying Copy_Handle.

In fact I have RDF.Auxilary.Simple_Handled_Record and some related (generic) 
packages defined like this:

[[[
with RDF.Auxilary.Handled_Record;

package RDF.Auxilary.Simple_Handled_Record is
   new RDF.Auxilary.Handled_Record(Dummy_Record);
]]]

So the solution to use child packages is not a good fit for me. (Well, I can 
rearrange the structure of my packages, but would not like this idea.)

Making it child packages to expose internal structure of object also should 
be eliminated if possible.

So now I see no really good way to do this. Any ideas?

> By the way, Dmitry's advice not to use re-dispatching is his personal
> opinion, shared by some people on comp.lang.ada but not by me; you
> should consider the pros and cons yourself.
> 
> Re-dispatching is what happens in your Adjust operation when you convert
> the Object to Base_Type'Class and then invoke Copy_Handle. The
> conversion forces the call to be a dispatching call. Without conversion,
> the call is statically bound to the Copy_Handle of Base_Object.
> 
> Re-dispatching plays no role in your problem. The problem is that by
> making Base_Object private, and Example_Record not a child of
> Handled_Record, you have made it impossible to create an Example_Object
> without first creating a Base_Object and therefore invoking the Adjust
> and Copy_Handle for Base_Object.

-- 
Victor Porton - http://portonvictor.org

  reply	other threads:[~2014-08-05 22:13 UTC|newest]

Thread overview: 73+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-08-05 20:09 A bad counterintuitive behaviour of Ada about OO Victor Porton
2014-08-05 20:58 ` Simon Wright
2014-08-05 21:06   ` Victor Porton
2014-08-05 21:51     ` Niklas Holsti
2014-08-05 22:13       ` Victor Porton [this message]
2014-08-05 22:35   ` Victor Porton
2014-08-05 23:25     ` Adam Beneschan
2014-08-05 20:59 ` Dmitry A. Kazakov
2014-08-05 21:07   ` Victor Porton
2014-08-05 22:39     ` Shark8
2014-08-05 21:11   ` Victor Porton
2014-08-06  7:26     ` Dmitry A. Kazakov
2014-08-07  7:41       ` Maciej Sobczak
2014-08-07  8:50         ` Dmitry A. Kazakov
2014-08-08  7:54           ` Maciej Sobczak
2014-08-08  8:14             ` Dmitry A. Kazakov
2014-08-08 13:06               ` Maciej Sobczak
2014-08-08 13:22                 ` Dmitry A. Kazakov
2014-08-08 22:32                   ` Randy Brukardt
2014-08-09 16:11                   ` Maciej Sobczak
2014-08-09 16:48                     ` Dmitry A. Kazakov
2014-08-10 20:55                       ` Maciej Sobczak
2014-08-11  7:41                         ` Dmitry A. Kazakov
2014-08-11  7:58                           ` Maciej Sobczak
2014-08-11  8:23                             ` Dmitry A. Kazakov
2014-08-12  7:50                               ` Maciej Sobczak
2014-08-11 11:35                             ` G.B.
2014-08-08 22:26                 ` Randy Brukardt
2014-08-08  8:34             ` Shark8
2014-08-08 12:59               ` Maciej Sobczak
2014-08-08 22:37                 ` Randy Brukardt
2014-08-08 22:53                   ` Jeffrey Carter
2014-08-07  8:58         ` J-P. Rosen
2014-08-07  9:40           ` Dmitry A. Kazakov
2014-08-07 11:17             ` J-P. Rosen
2014-08-07 12:28               ` Dmitry A. Kazakov
2014-08-07 13:34                 ` J-P. Rosen
2014-08-07 16:10                   ` Dmitry A. Kazakov
2014-08-07 18:14                     ` Robert A Duff
2014-08-07 19:41                       ` Dmitry A. Kazakov
2014-08-07 20:53                         ` Robert A Duff
2014-08-08  7:43                           ` Dmitry A. Kazakov
2014-08-08  8:18                             ` Shark8
2014-08-08  7:45                     ` J-P. Rosen
2014-08-08  8:04                       ` Dmitry A. Kazakov
2014-08-08  8:55                         ` J-P. Rosen
2014-08-08  9:13                           ` Dmitry A. Kazakov
2014-08-08 10:01                             ` J-P. Rosen
2014-08-08 10:53                               ` Dmitry A. Kazakov
2014-08-08 10:56                                 ` Victor Porton
2014-08-08 12:00                                 ` J-P. Rosen
2014-08-08 13:11                                   ` Dmitry A. Kazakov
2014-08-08 13:53                                     ` J-P. Rosen
2014-08-08 20:23                                       ` Dmitry A. Kazakov
2014-08-07 20:29                   ` Shark8
2014-08-08  7:49                     ` J-P. Rosen
2014-08-08  8:12                       ` Shark8
2014-08-08  8:26                         ` Dmitry A. Kazakov
2014-08-08 11:10                           ` Shark8
2014-08-08 11:20                             ` Dmitry A. Kazakov
2014-08-08 19:34                               ` Shark8
2014-08-08 20:23                                 ` Dmitry A. Kazakov
2014-08-07 15:03           ` Jeffrey Carter
2014-08-08  7:48           ` Maciej Sobczak
2014-08-08  8:51             ` J-P. Rosen
2014-08-08 13:25               ` Maciej Sobczak
2014-08-08 13:34                 ` J-P. Rosen
2014-08-08 13:52                   ` Dmitry A. Kazakov
2014-08-08 14:21                     ` J-P. Rosen
2014-08-08 20:23                       ` Dmitry A. Kazakov
2014-08-08 22:08                     ` Randy Brukardt
2014-08-08 22:18                 ` Randy Brukardt
2014-08-06  4:50 ` Per Sandberg
replies disabled

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