comp.lang.ada
 help / color / mirror / Atom feed
* Private area and child packages
@ 2004-12-29  4:05 danmcleran
  2004-12-29  4:47 ` tmoran
                   ` (3 more replies)
  0 siblings, 4 replies; 15+ messages in thread
From: danmcleran @ 2004-12-29  4:05 UTC (permalink / raw)


Is there any way to hide implementation detail from child packages? An
example, say I have a parent package like this:

package Some_Package is
type Secret_Type is private;
private
type Secret_Type is record
Secret_Value : Integer := 0;
end record;
end Some_Package;

I don't want any other component to be able to manipulate the
Secret_Value record component, not even a child package of
Some_Package.

Is there any way to do this? In C++, there is something called the
PIMPL idiom, where you hide implementation detail by holding a pointer
to an incomplete class, like this:

//SecretClass.h

class Implementation;//Class not yet fully defined

class SecretClass
{
public:
//publicly visible stuff
private:
Implementation* pImplementation;
};

So, no component outside of the implementation of SecretClass, (not
even other classes that inherit SecretClass), has any knowledge of the
structure of the implementation class. The full definition of the
Implementation class is not provided in the header containing the
definition of SecretClass. The Implementation class can either be
defined in the cpp file that defines SecretClass, or seperately.

I'm trying to figure out the most elegant way to do something like this
is Ada and would like to read any ideas/suggestions.




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

* Re: Private area and child packages
  2004-12-29  4:05 Private area and child packages danmcleran
@ 2004-12-29  4:47 ` tmoran
  2004-12-29 15:10   ` danmcleran
  2004-12-29  4:49 ` Jeffrey Carter
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 15+ messages in thread
From: tmoran @ 2004-12-29  4:47 UTC (permalink / raw)


How about renaming Some_Package.Child_Package to
Some_Package_Child_Package, ie, don't make it a child package.
The usual reason for making something a child package is to allow it
visibility into the parent, which is exactly what you don't want here.
So for what reason are you using the child package mechanism?



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

* Re: Private area and child packages
  2004-12-29  4:05 Private area and child packages danmcleran
  2004-12-29  4:47 ` tmoran
@ 2004-12-29  4:49 ` Jeffrey Carter
  2004-12-29 15:27   ` danmcleran
                     ` (3 more replies)
  2004-12-29 19:05 ` Martin Krischik
  2004-12-29 21:44 ` Stephen Leake
  3 siblings, 4 replies; 15+ messages in thread
From: Jeffrey Carter @ 2004-12-29  4:49 UTC (permalink / raw)


danmcleran@hotmail.com wrote:

> Is there any way to hide implementation detail from child packages? An
> example, say I have a parent package like this:
> 
> package Some_Package is
> type Secret_Type is private;
> private
> type Secret_Type is record
> Secret_Value : Integer := 0;
> end record;
> end Some_Package;
> 
> I don't want any other component to be able to manipulate the
> Secret_Value record component, not even a child package of
> Some_Package.

If you don't need to make the type visible at all, you can simply 
declare it in the package body. Items in package bodies are hidden from 
all other scopes.

If you want the type to be visible, but its implementation to be hidden, 
you can use a pointer:

package P is
    type Something is [limited] private;

    -- operations on Something
private -- P
    type Implementation;
    type Something is access [all] Implementation;
end P;

The full view of Implementation must then be given in the body of P. If 
you do this, you're responsible for the memory management of Something. 
This is usually easier if you make Something limited, since the client 
cannot then make copies of the access values, eliminating opportunities 
for dangling references.

-- 
Jeff Carter
"Beyond 100,000 lines of code you
should probably be coding in Ada."
P. J. Plauger
26



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

* Re: Private area and child packages
  2004-12-29  4:47 ` tmoran
@ 2004-12-29 15:10   ` danmcleran
  2004-12-30 18:51     ` tmoran
  0 siblings, 1 reply; 15+ messages in thread
From: danmcleran @ 2004-12-29 15:10 UTC (permalink / raw)



tmoran@acm.org wrote:
> How about renaming Some_Package.Child_Package to
> Some_Package_Child_Package, ie, don't make it a child package.
> The usual reason for making something a child package is to allow it
> visibility into the parent, which is exactly what you don't want
here.
> So for what reason are you using the child package mechanism?
What I was wondering was how someone writing Some_Package can enforce
this on future package writers. I could obviously follow your
suggestion if I am the only developer writing code for a project. But,
if I want to hide implementation details from someone else who might
write a child package, I would need some mechanism to enforce this
information hiding.




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

* Re: Private area and child packages
  2004-12-29  4:49 ` Jeffrey Carter
@ 2004-12-29 15:27   ` danmcleran
  2004-12-29 16:53     ` Samuel Tardieu
  2004-12-30 15:31   ` danmcleran
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 15+ messages in thread
From: danmcleran @ 2004-12-29 15:27 UTC (permalink / raw)


This is exactly what I was looking for. By the way. where did you find
that quote from P.J. Plauger?




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

* Re: Private area and child packages
  2004-12-29 15:27   ` danmcleran
@ 2004-12-29 16:53     ` Samuel Tardieu
  2004-12-30  4:07       ` Jeffrey Carter
  0 siblings, 1 reply; 15+ messages in thread
From: Samuel Tardieu @ 2004-12-29 16:53 UTC (permalink / raw)


>>>>> "D" == danmcleran  <danmcleran@hotmail.com> writes:

D> This is exactly what I was looking for. By the way. where did you
D> find that quote from P.J. Plauger?

Maybe from here:

  http://archive.adaic.com/docs/present/ajpo/pll-cost/html/tsld071.htm

 Sam
-- 
Samuel Tardieu -- sam@rfc1149.net -- http://www.rfc1149.net/sam



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

* Re: Private area and child packages
  2004-12-29  4:05 Private area and child packages danmcleran
  2004-12-29  4:47 ` tmoran
  2004-12-29  4:49 ` Jeffrey Carter
@ 2004-12-29 19:05 ` Martin Krischik
  2004-12-29 21:44 ` Stephen Leake
  3 siblings, 0 replies; 15+ messages in thread
From: Martin Krischik @ 2004-12-29 19:05 UTC (permalink / raw)


danmcleran@hotmail.com wrote:

> Is there any way to do this? In C++, there is something called the
> PIMPL idiom, where you hide implementation detail by holding a pointer
> to an incomplete class, like this:

> //SecretClass.h
> 
> class Implementation;//Class not yet fully defined
> 
> class SecretClass
> {
> public:
> //publicly visible stuff
> private:
> Implementation* pImplementation;

using:

Implementation& pImplementation;

will prevent the generation of a faulty operator = () ;-). You then use:

pImplementation = *new Implementation;
delete &pImplementation ;

Looky wacky but is perfectly legal.

> };

You do it the same way in Ada as in C. Use:

type Implementation_Type;
type Implementation is access Implementation_Type;

With Regards

Martin
-- 
mailto://krischik@users.sourceforge.net
http://www.ada.krischik.com



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

* Re: Private area and child packages
  2004-12-29  4:05 Private area and child packages danmcleran
                   ` (2 preceding siblings ...)
  2004-12-29 19:05 ` Martin Krischik
@ 2004-12-29 21:44 ` Stephen Leake
  3 siblings, 0 replies; 15+ messages in thread
From: Stephen Leake @ 2004-12-29 21:44 UTC (permalink / raw)
  To: comp.lang.ada

danmcleran@hotmail.com writes:

> I don't want any other component to be able to manipulate the
> Secret_Value record component, not even a child package of
> Some_Package.
> 
> Is there any way to do this? In C++, there is something called the
> PIMPL idiom, where you hide implementation detail by holding a pointer
> to an incomplete class, like this:
> 
> //SecretClass.h
> 
> class Implementation;//Class not yet fully defined
> 
> class SecretClass
> {
> public:
> //publicly visible stuff
> private:
> Implementation* pImplementation;
> };

Use the same mechanism in Ada; declare an incomplete type and a
pointer to it:

package Some_Package is
   type Secret_Type is private;
private

   type Really_Secret_Type;
   type Access_Really_Secret_Type is access Really_Secret_Type;

   type Secret_Type is record
      Secret_Value : Access_Really_Secret_Type;
   end record;
end Some_Package;

-- 
-- Stephe




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

* Re: Private area and child packages
  2004-12-29 16:53     ` Samuel Tardieu
@ 2004-12-30  4:07       ` Jeffrey Carter
  0 siblings, 0 replies; 15+ messages in thread
From: Jeffrey Carter @ 2004-12-30  4:07 UTC (permalink / raw)


Samuel Tardieu wrote:

>>>>>>"D" == danmcleran  <danmcleran@hotmail.com> writes:
> 
> D> This is exactly what I was looking for. By the way. where did you
> D> find that quote from P.J. Plauger?
> 
> Maybe from here:
> 
>   http://archive.adaic.com/docs/present/ajpo/pll-cost/html/tsld071.htm

and from

http://www.sysprog.net/quotada.html

There are probably a lot of places it can be found.

-- 
Jeff Carter
"Spam! Spam! Spam! Spam! Spam! Spam! Spam! Spam!"
Monty Python's Flying Circus
53



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

* Re: Private area and child packages
  2004-12-29  4:49 ` Jeffrey Carter
  2004-12-29 15:27   ` danmcleran
@ 2004-12-30 15:31   ` danmcleran
  2004-12-30 18:14     ` Jeffrey Carter
  2004-12-31 17:55   ` danmcleran
       [not found]   ` <1104515735.052116.248180@c13g2000cwb.googlegroups.com>
  3 siblings, 1 reply; 15+ messages in thread
From: danmcleran @ 2004-12-30 15:31 UTC (permalink / raw)


What about using Ada's Limited_Controlled type? Then, since no copies
could be made, I could do something like this:

with Ada.Finalization;

package Some_Package is
type Secret_Type is tagged limited private;
private
type Implementation_Type;
type Implementation_Access_Type is access Implementation_Type;
type Secret_Type is new Ada.Finalization.Limited_Controlled with
record
Implementation_Access : Implementation_Access_Type := null;
end record;   
end Some_Package;




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

* Re: Private area and child packages
  2004-12-30 15:31   ` danmcleran
@ 2004-12-30 18:14     ` Jeffrey Carter
  0 siblings, 0 replies; 15+ messages in thread
From: Jeffrey Carter @ 2004-12-30 18:14 UTC (permalink / raw)


danmcleran@hotmail.com wrote:

> What about using Ada's Limited_Controlled type? Then, since no copies
> could be made, I could do something like this:
> 
> with Ada.Finalization;
> 
> package Some_Package is
> type Secret_Type is tagged limited private;
> private
> type Implementation_Type;
> type Implementation_Access_Type is access Implementation_Type;
> type Secret_Type is new Ada.Finalization.Limited_Controlled with
> record
> Implementation_Access : Implementation_Access_Type := null;
> end record;   
> end Some_Package;

Don't forget to override Finalize.

This doesn't really do what you want, since a child can see and copy the 
access component:

package body Some_Package.Child is
    A : Implementation_Access_Type

    procedure Op (L : Secret_Type) is
       -- null;
    begin -- Op
       A := L.Implementation_Access;
    end Op;

    ...
end Some_Package.Child;

It's possible for the actual of L to go out of scope and be finalized, 
deallocating L.Implementation_Access, while A is still around, a 
dangling reference.

-- 
Jeff Carter
"Now look, Col. Batguano, if that really is your name."
Dr. Strangelove
31



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

* Re: Private area and child packages
  2004-12-29 15:10   ` danmcleran
@ 2004-12-30 18:51     ` tmoran
  2005-01-01  3:45       ` danmcleran
  0 siblings, 1 reply; 15+ messages in thread
From: tmoran @ 2004-12-30 18:51 UTC (permalink / raw)


>What I was wondering was how someone writing Some_Package can enforce
>this on future package writers. I could obviously follow your
>suggestion if I am the only developer writing code for a project. But,
>if I want to hide implementation details from someone else who might
>write a child package, I would need some mechanism to enforce this
>information hiding.
   You could burn the only copy of the source code.  Seriously, how
else could you enforce such a restriction on future developers who
want to fiddle with/fix your code?  Even if the compiler would
allow such a limit (say by disallowing child packages) what would
prevent someone from simply modifying your code, say by moving the
"hidden" declaration from the private to the public part of the spec?
Or, if they can't modify your code, but can find a copy of the source
somewhere, they could declare their own structure to match yours, and
use an address clause to overlay their (visible) structure over yours.
  Part of the Ada Style is a certain humility.  Assuming that your
code and your design is so perfect that any change by anyone in the
future is bad, is unwise, as shown by much sad experience.  IMHO



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

* Re: Private area and child packages
  2004-12-29  4:49 ` Jeffrey Carter
  2004-12-29 15:27   ` danmcleran
  2004-12-30 15:31   ` danmcleran
@ 2004-12-31 17:55   ` danmcleran
       [not found]   ` <1104515735.052116.248180@c13g2000cwb.googlegroups.com>
  3 siblings, 0 replies; 15+ messages in thread
From: danmcleran @ 2004-12-31 17:55 UTC (permalink / raw)


Jeffrey Carter wrote:
> danmcleran@hotmail.com wrote:
>
> > Is there any way to hide implementation detail from child packages?
An
> > example, say I have a parent package like this:
> >
> > package Some_Package is
> > type Secret_Type is private;
> > private
> > type Secret_Type is record
> > Secret_Value : Integer := 0;
> > end record;
> > end Some_Package;
> >
> > I don't want any other component to be able to manipulate the
> > Secret_Value record component, not even a child package of
> > Some_Package.
>
> If you don't need to make the type visible at all, you can simply
> declare it in the package body. Items in package bodies are hidden
from
> all other scopes.
>
> If you want the type to be visible, but its implementation to be
hidden,
> you can use a pointer:
>
> package P is
>     type Something is [limited] private;
>
>     -- operations on Something
> private -- P
>     type Implementation;
>     type Something is access [all] Implementation;
> end P;
>
> The full view of Implementation must then be given in the body of P.
If
> you do this, you're responsible for the memory management of
Something.
> This is usually easier if you make Something limited, since the
client
> cannot then make copies of the access values, eliminating
opportunities
> for dangling references.
>
> --
> Jeff Carter
> "Beyond 100,000 lines of code you
> should probably be coding in Ada."
> P. J. Plauger
> 26


But then how do I know when the access to the Implementation object
goes out of scope? It seems to me that I need to either derive from
Ada.Finalization.Limited_Controlled or define Something as a smart
pointer to Implementation.




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

* Re: Private area and child packages
       [not found]   ` <1104515735.052116.248180@c13g2000cwb.googlegroups.com>
@ 2004-12-31 19:02     ` Jeffrey Carter
  0 siblings, 0 replies; 15+ messages in thread
From: Jeffrey Carter @ 2004-12-31 19:02 UTC (permalink / raw)


danmcleran@hotmail.com wrote:
> 
> But then how do I know when the access to the Implementation object
> goes out of scope? It seems to me that I need to either derive from
> Ada.Finalization.Limited_Controlled or define Something as a smart
> pointer to Implementation.

Yes, to manage memory the best approach is a controlled type. Smart 
pointers are good because they do reference counting and eliminate 
dangling references.

There doesn't seem to be any way to prevent a child package from making 
copies of access values if you decide to hide the implementation of a 
visible type in the package body.

-- 
Jeff Carter
"Ada has made you lazy and careless. You can write programs in C that
are just as safe by the simple application of super-human diligence."
E. Robert Tisdale
72



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

* Re: Private area and child packages
  2004-12-30 18:51     ` tmoran
@ 2005-01-01  3:45       ` danmcleran
  0 siblings, 0 replies; 15+ messages in thread
From: danmcleran @ 2005-01-01  3:45 UTC (permalink / raw)



tmoran@acm.org wrote:
>    You could burn the only copy of the source code.  Seriously, how
> else could you enforce such a restriction on future developers who
> want to fiddle with/fix your code?

Isn't that what abstraction and encapsulation is all about? In your
designs, do you make eveything public because it can be done that way
by some future developer anyway?

> Even if the compiler would
> allow such a limit (say by disallowing child packages) what would
> prevent someone from simply modifying your code, say by moving the
> "hidden" declaration from the private to the public part of the spec?

If you take this argument to its logical extreme, then all of the time
and effort that has gone into creating programming languages to provide
features such as abstraction & encapsulation has been a giant waste of
time. Since anyone could always make private data public any time they
choose, why not just stick with assembly language(s) or C? Why not just
make everything public all of the time?

> Or, if they can't modify your code, but can find a copy of the source
> somewhere, they could declare their own structure to match yours, and
> use an address clause to overlay their (visible) structure over
yours.

This seems like a pretty far-fetched counter-argument.

>   Part of the Ada Style is a certain humility.  Assuming that your
> code and your design is so perfect that any change by anyone in the
> future is bad, is unwise, as shown by much sad experience.  IMHO

I would agree, but I would also argue that it is in the best interests
of a good software design to only expose what is absolutely necessary
to be exposed.




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

end of thread, other threads:[~2005-01-01  3:45 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-12-29  4:05 Private area and child packages danmcleran
2004-12-29  4:47 ` tmoran
2004-12-29 15:10   ` danmcleran
2004-12-30 18:51     ` tmoran
2005-01-01  3:45       ` danmcleran
2004-12-29  4:49 ` Jeffrey Carter
2004-12-29 15:27   ` danmcleran
2004-12-29 16:53     ` Samuel Tardieu
2004-12-30  4:07       ` Jeffrey Carter
2004-12-30 15:31   ` danmcleran
2004-12-30 18:14     ` Jeffrey Carter
2004-12-31 17:55   ` danmcleran
     [not found]   ` <1104515735.052116.248180@c13g2000cwb.googlegroups.com>
2004-12-31 19:02     ` Jeffrey Carter
2004-12-29 19:05 ` Martin Krischik
2004-12-29 21:44 ` Stephen Leake

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