comp.lang.ada
 help / color / mirror / Atom feed
* Another OOP Question
@ 1996-08-18  0:00 Spasmo
  1996-08-19  0:00 ` Jon S Anthony
  0 siblings, 1 reply; 8+ messages in thread
From: Spasmo @ 1996-08-18  0:00 UTC (permalink / raw)



Hey all, me again :)

Ok, here's another OOP question about accessing private members.
Right now let's say I have a class called A, and B inherits from
A.  Now let's say that B needs to access a private data member
in A -- is there any way I can do this without placing B into
a Child package?  The reason I'd like to now is because I'm
confronted with such a scenario and Child packages (among other
things) will make all of my parents members visible which is
the last thing I want to do.

Thanks for any assistance.


--
Spasmo
"Everyone has secrets, but sometimes you get caught,
 So if it's just between us, my silence can be bought"
	"Blackmail" by Sloppy Seconds





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

* Re: Another OOP Question
  1996-08-18  0:00 Spasmo
@ 1996-08-19  0:00 ` Jon S Anthony
  0 siblings, 0 replies; 8+ messages in thread
From: Jon S Anthony @ 1996-08-19  0:00 UTC (permalink / raw)



In article <4v609i$fgj@Masala.CC.UH.EDU> cosc19z5@Bayou.UH.EDU (Spasmo) writes:

> Ok, here's another OOP question about accessing private members.
> Right now let's say I have a class called A, and B inherits from
> A.  Now let's say that B needs to access a private data member
> in A -- is there any way I can do this without placing B into
> a Child package?  

I'm not sure I follow this.  Do you mean "private" in the C++ sense or in
the Ada sense?  In the Ada sense, if A and B are in the same package, then
you get this for free:

package P is

    type A is tagged private;
    ... ops for A...
    type B is new A with private;
    ... ops for B...

private
    type A is ...
    type B is ...
end P;

In the body of P, B's ops can access A's private definition no problem.


If you want A and B in separate packages, then in order for the impls of
B's ops to have access to the private definition of A, it needs to go into
a child package.

> The reason I'd like to now is because I'm confronted with such a
> scenario and Child packages (among other things) will make all of my
> parents members visible which is the last thing I want to do.

I don't understand why you make this claim.  Children do not make any of
the private stuff of the parent visible:

package P is
    type A is tagged private;
    ...
private
    type A is...
end P;


package P.C is
--
-- None of P's private definitions are visible here.
    type B is new A with private;
    ...
private
--
-- P's private section is visible here and in the body of P.C
    type B is ...
end P.C;


with P.C;
procedure Proc is
--
-- Nothing of P's private section is visible here...
...
end Proc;


My guess is that you are not clear on child package visibility rules
and that you really do want to use a child package and that it will
work just fine for what you want to achieve.

Lastly, if you mean "private" in the C++ sense, you have to put the actual
definitions in the _bodies_ of the packages.  The only way for anything
else to get at these will be through accessors (public or private) defined
in the specification.  Nothing outside the body (and any separates) has
direct access.

/Jon
-- 
Jon Anthony
Organon Motives, Inc.
1 Williston Road, Suite 4
Belmont, MA 02178

617.484.3383
jsa@organon.com





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

* Re: Another OOP Question
  1996-08-20  0:00 Spasmo
@ 1996-08-20  0:00 ` Jon S Anthony
  1996-08-20  0:00   ` Robert I. Eachus
  0 siblings, 1 reply; 8+ messages in thread
From: Jon S Anthony @ 1996-08-20  0:00 UTC (permalink / raw)



In article <4vblni$j29@Masala.CC.UH.EDU> cosc19z5@Bayou.UH.EDU (Spasmo) writes:

> Jon S Anthony (jsa@alexandria) wrote:
> : In article <4v609i$fgj@Masala.CC.UH.EDU> cosc19z5@Bayou.UH.EDU (Spasmo) writes:
[....]
> : If you want A and B in separate packages, then in order for the impls of
> : B's ops to have access to the private definition of A, it needs to go into
> : a child package.
> 
> Right, that's pretty much the scenario I'm working with.  I'm
> using class to mean a tagged datatype and its associated
> functions all placed into a package since that's how I'm doing
> things, but of course others may do things differently so
> forgive the error (and arrogance).

Sounds fine to me.  No error or arrogance.


> : I don't understand why you make this claim.  Children do not make any of
> : the private stuff of the parent visible:
> 
> Are you sure about this?  I was able to pick into the private
> goodies of my parent when I declared a child class in Gnat3.05
> for DOS.  It was something like this:
> 
> The package with the parent had a class that was tagged private.
> I declared a child package and was able to use the data fields
> 	of the class in the parent that were private.

Yes, I'm sure.  But the problem is we are talking about different
things and so it is no wonder we are not communicating.  What you are
really concerned about here is that the _private_ section of a child
has access to the _private_ section of the parent (and the visible
part too, of course).  If GNAT is allowing the _visible_ part of the
child access to the private part of the parent (and that child is NOT
a private child), then GNAT is broken.  Report the bug.

A child is really an extension of the declarative region of the
parent.  Some people (as you indicate for yourself) have voiced
concerns about this.  For myself, I see it as simply a case of
recognizing what is happening and being appropriately careful.

Another point that may be confusing you is that "private" in Ada is
really the analogue of "protected" in C++.  The "private" of C++ is
achieved by use of package _bodies_ (which have no analogue in C++)


> Well yes I know of the above, again I'm being vague.  I meant
> that the child package could see the parent package's private
> goodies, not that the child package would make the parent's
> private goodies available to whatever package with'ed it. 

But _only_ the _private_ section of the child can see these private
goodies of the parent.  So the visible part of the child has no more
access to the private section of the parent than a standard client.


> Well I knew about the above so I believe I'm relatively clear
> on the visibility rules.  What was troubling me was that the
> way I was doing it was making all of my parent's private stuff
> visible to the child, rather than finding a way to just access
> the one member I wanted in question.  Of course I could try
> returning a pointer to the internal aliased type and indirectly
> manipulate it through there, but the thing would be clumsy and
> once again it wouldn't change having to deal with the child
> package (unless I wanted this to be available to all!).

OK, I know you have some concerns about this, but it is not clear
what they are or more to the point why you have them.  I also don't
understand what you mean by this phrase "available to all".  To "all"
what"?


> designer is confronted with.  There's a data item whose direct
> access may be of great use to any children.  At this point in
> time the designer cannot visualize what the children might
> do with it, but he/she realizes that being able to directly
> access this data item can be of importance.  Now the designer
> wants to make this data item visible without making anything
> else visible, but at the same time this person cannot just
> make this data item visible to everything -- only children.
> 
> The scenario is similar to C++'s protected types.  Here
> you have items that cannot be accessed except by inherited
> classes,                                         ^^^^^^^^^ Sub

> and the thing is you can have protected types
> and private types mixed in so that only the stuff you want
> to be protected is in fact protected.  Ok so far so good?

Yes.


> Now with Ada you have the private section of a package.
> This makes everything private but child packages can see
> into this.  The problem is that if you use child packages
> the children can see EVERYTHING.

Yes, just like in C++ any child can see ALL the "protected" stuff.
If you want the _C++_ private bit, too, put the definitions in the
_body_.  Then they are _only_ visible there and no where else!
Another route that is more flexible (but pays for it by letting in
more possible "seers") is to use a _private_ child package.


> that the output is double buffered.  Naturally to share
> the screen items need to be able to access the current
> buffer.

This sounds like a classic shared resource

Suggestion: Capture it with a protected type.


> Now the box class has an access to the buffer
> so it can modify it (via alias), but of course to be able
> to write to the same screen children need to be able
> to get a hold of this buffer since they want to do more
> with it.  Ie: the next child is a textbox so it needs
> to put text in the box and it needs to get the buffer
> to do this.

Definitely use a protected type.  This is off topic from your concern
about C++ style "private"/"protected" stuff, but it will make your
current problem evaporate.  Egads, note too, that "protected type" in
Ada has nothing to do with "protected" in C++.


> mess such a function would have to be made public

Why???

package P is
    type A is tagged private;
    ...
private
    type A is tagged ...
    ...
    protected Buffer is
        function Get...
        entry Put....
    private
        The_Buffer : ... I guess something to do with A...
    end Buffer;
end P;

Only children can see Buffer and ONLY in their private section or
bodies.  Buffer is _NOT_ public.  More over, The_Buffer is not even
visible to the children or even the other things in P!  It is ONLY
visible in the body of Buffer.


> Messed up isn't it?  Maybe my whole concept of how
> I'm doing this is flawed, but still am I right in
> assuming that there is nothing equivalent to
> C++'s protected type?  

Absolutely not.  The equivalent is Ada private section definitions.


/Jon
-- 
Jon Anthony
Organon Motives, Inc.
1 Williston Road, Suite 4
Belmont, MA 02178

617.484.3383
jsa@organon.com





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

* Re: Another OOP Question
  1996-08-20  0:00 ` Jon S Anthony
@ 1996-08-20  0:00   ` Robert I. Eachus
  0 siblings, 0 replies; 8+ messages in thread
From: Robert I. Eachus @ 1996-08-20  0:00 UTC (permalink / raw)




     I assume that the problem is that you want only part of the
private properties of the parent to be visible to the child.
There is a trick you can use in Ada 95 which may help with what
you want.  Actually, make that two tricks...

     package Foo is

       type Parent is tagged private;
       --visible methods on parent

     private

       package Hidden is
         type Real_Parent is tagged private;
         -- some partially hidden methods here.
       private
         type Real_Parent is tagged record....
         --really well hidden methods here.
       end Hidden;
        
       type Parent is new Real_Parent with...
       -- hidden methods here too.

     end Foo;      
 
     Now in children the public methods will be visible.  In the
private part, the hidden methods will be visible, but the state
variables declared in the private part of Hidden.Real_Parent will not
be visible.  Also the operations in the private part of Hidden will be
derived, but will not be visible in any children or directly in the
body of Foo.  Unless they override visible methods--for instance if
Real_Parent is a derived type--the only way to access the really well
hiden methods is through the visible operations in Hidden.
         
    Oh, I promised you a second way:

     package Foo is

       type Parent is tagged private;
       --visible methods on parent

     private

       type Parent is new with...

       package Hidden is
         -- some partially hidden methods here.
       private
         --really well hidden methods here.
       end Hidden;
        
       -- and some hidden methods here.

     end Foo;      
 
     In this method the operations in Hidden are not derived for type
Parent which may be and advantage.  The visible operations in Hidden
can be used on child types, but you need to do explicit conversions.
This technique is very useful if you are defining operations which
shouldn't be implicitly derived for child types.


--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...




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

* Re: Another OOP Question
@ 1996-08-20  0:00 Spasmo
  1996-08-20  0:00 ` Jon S Anthony
  0 siblings, 1 reply; 8+ messages in thread
From: Spasmo @ 1996-08-20  0:00 UTC (permalink / raw)



Jon S Anthony (jsa@alexandria) wrote:
: In article <4v609i$fgj@Masala.CC.UH.EDU> cosc19z5@Bayou.UH.EDU (Spasmo) writes:

: > Ok, here's another OOP question about accessing private members.
: > Right now let's say I have a class called A, and B inherits from
: > A.  Now let's say that B needs to access a private data member
: > in A -- is there any way I can do this without placing B into
: > a Child package?  

: I'm not sure I follow this.  Do you mean "private" in the C++ sense or in
: the Ada sense?  In the Ada sense, if A and B are in the same package, then
: you get this for free:

Well private in the Ada sense.  As usual I'm being way too
vague (I need to get out of this habit!).  I've got a class
defined in one package, and an inherited class in another
package so I'm speaking of 2 classes in 2 different packages.
That's pretty much how I'm trying to commit myself in terms
of doing things.  Ada provides such awesome modular programming
support that there's no reason not to use it.

[Example snipped, it was about another scenario]


: If you want A and B in separate packages, then in order for the impls of
: B's ops to have access to the private definition of A, it needs to go into
: a child package.

Right, that's pretty much the scenario I'm working with.  I'm
using class to mean a tagged datatype and its associated
functions all placed into a package since that's how I'm doing
things, but of course others may do things differently so
forgive the error (and arrogance).


: > The reason I'd like to now is because I'm confronted with such a
: > scenario and Child packages (among other things) will make all of my
: > parents members visible which is the last thing I want to do.

: I don't understand why you make this claim.  Children do not make any of
: the private stuff of the parent visible:

Are you sure about this?  I was able to pick into the private
goodies of my parent when I declared a child class in Gnat3.05
for DOS.  It was something like this:

The package with the parent had a class that was tagged private.
I declared a child package and was able to use the data fields
	of the class in the parent that were private.



: package P is
:     type A is tagged private;
:     ...
: private
:     type A is...
: end P;


: package P.C is
: --
: -- None of P's private definitions are visible here.
:     type B is new A with private;
:     ...
: private
: --
: -- P's private section is visible here and in the body of P.C
:     type B is ...
: end P.C;


: with P.C;
: procedure Proc is
: --
: -- Nothing of P's private section is visible here...
: ...
: end Proc;

Well yes I know of the above, again I'm being vague.  I meant
that the child package could see the parent package's private
goodies, not that the child package would make the parent's
private goodies available to whatever package with'ed it. 


: My guess is that you are not clear on child package visibility rules
: and that you really do want to use a child package and that it will
: work just fine for what you want to achieve.

Well I knew about the above so I believe I'm relatively clear
on the visibility rules.  What was troubling me was that the
way I was doing it was making all of my parent's private stuff
visible to the child, rather than finding a way to just access
the one member I wanted in question.  Of course I could try
returning a pointer to the internal aliased type and indirectly
manipulate it through there, but the thing would be clumsy and
once again it wouldn't change having to deal with the child
package (unless I wanted this to be available to all!).



: Lastly, if you mean "private" in the C++ sense, you have to put the actual
: definitions in the _bodies_ of the packages.  The only way for anything
: else to get at these will be through accessors (public or private) defined
: in the specification.  Nothing outside the body (and any separates) has
: direct access.

Ok, I'll try to be precise in what I am trying to do and use an
example from *gasp* C++.  I should have done this from the start
but to be honest I didn't want to drag C++ in there since
the more I use Ada the more I look down on C++, but it seems
that for example's sake this may be the way to go.

Ok, consider this scenario.  A person is working on a an OO package.
This package defines a class and all the operations to be performed
on this class.  No problemo so far, but there's something the
designer is confronted with.  There's a data item whose direct
access may be of great use to any children.  At this point in
time the designer cannot visualize what the children might
do with it, but he/she realizes that being able to directly
access this data item can be of importance.  Now the designer
wants to make this data item visible without making anything
else visible, but at the same time this person cannot just
make this data item visible to everything -- only children.

The scenario is similar to C++'s protected types.  Here
you have items that cannot be accessed except by inherited
classes, and the thing is you can have protected types
and private types mixed in so that only the stuff you want
to be protected is in fact protected.  Ok so far so good?

Now with Ada you have the private section of a package.
This makes everything private but child packages can see
into this.  The problem is that if you use child packages
the children can see EVERYTHING.

The precise scenario that I'm confronted with is this.
I'm working on some menu classes to get more familiarized
with OOP in Ada.  Anyway I've written some wrappers for
enhanced I/O by accessing C classes and I've made it so
that the output is double buffered.  Naturally to share
the screen items need to be able to access the current
buffer.  Now the box class has an access to the buffer
so it can modify it (via alias), but of course to be able
to write to the same screen children need to be able
to get a hold of this buffer since they want to do more
with it.  Ie: the next child is a textbox so it needs
to put text in the box and it needs to get the buffer
to do this.

Now there is one idea and that's just having a function
that returns an access to this buffer so that we can
get the screen that we're working on.  Of course the
problem is that in order to circumvent this whole
mess such a function would have to be made public
which would give other non-related units access
to this private data member (via an alias).

Messed up isn't it?  Maybe my whole concept of how
I'm doing this is flawed, but still am I right in
assuming that there is nothing equivalent to
C++'s protected type?  

Wow what a mouthfull! :)
 

: /Jon
: -- 
: Jon Anthony
: Organon Motives, Inc.
: 1 Williston Road, Suite 4
: Belmont, MA 02178

: 617.484.3383
: jsa@organon.com


--
Spasmo
"Everyone has secrets, but sometimes you get caught,
 So if it's just between us, my silence can be bought"
	"Blackmail" by Sloppy Seconds





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

* Re: Another OOP Question
@ 1996-08-21  0:00 Spasmo
  0 siblings, 0 replies; 8+ messages in thread
From: Spasmo @ 1996-08-21  0:00 UTC (permalink / raw)



Robert I. Eachus (eachus@spectre.mitre.org) wrote:

:      I assume that the problem is that you want only part of the
: private properties of the parent to be visible to the child.
: There is a trick you can use in Ada 95 which may help with what
: you want.  Actually, make that two tricks...

[Examples snipped]

Hey talk about sneaky!  :).  I went ahead and saved this article so
I can study the examples in detail.  I must admit I didn't know that
you could declare embedded packages, but this is certainly an idea to 
work with.  Thanks!



: --

: 					Robert I. Eachus

: with Standard_Disclaimer;
: use  Standard_Disclaimer;
: function Message (Text: in Clever_Ideas) return Better_Ideas is...

--
Spasmo
"Everyone has secrets, but sometimes you get caught,
 So if it's just between us, my silence can be bought"
	"Blackmail" by Sloppy Seconds





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

* Re: Another OOP Question
@ 1996-08-21  0:00 Spasmo
  1996-08-22  0:00 ` Jon S Anthony
  0 siblings, 1 reply; 8+ messages in thread
From: Spasmo @ 1996-08-21  0:00 UTC (permalink / raw)



Jon S Anthony (jsa@alexandria) wrote:
: In article <4vblni$j29@Masala.CC.UH.EDU> cosc19z5@Bayou.UH.EDU (Spasmo) writes:

: > Jon S Anthony (jsa@alexandria) wrote:
: > : In article <4v609i$fgj@Masala.CC.UH.EDU> cosc19z5@Bayou.UH.EDU (Spasmo) writes:
: [....]
: > : If you want A and B in separate packages, then in order for the impls of
: > : B's ops to have access to the private definition of A, it needs to go into
: > : a child package.
: > 
: > Right, that's pretty much the scenario I'm working with.  I'm
: > using class to mean a tagged datatype and its associated
: > functions all placed into a package since that's how I'm doing
: > things, but of course others may do things differently so
: > forgive the error (and arrogance).

: Sounds fine to me.  No error or arrogance.

Ok cool (I just have the tendency to make assumptions so at times
I can be really vague).  


: > : I don't understand why you make this claim.  Children do not make any of
: > : the private stuff of the parent visible:
: > 
: > Are you sure about this?  I was able to pick into the private
: > goodies of my parent when I declared a child class in Gnat3.05
: > for DOS.  It was something like this:
: > 
: > The package with the parent had a class that was tagged private.
: > I declared a child package and was able to use the data fields
: > 	of the class in the parent that were private.

: Yes, I'm sure.  But the problem is we are talking about different
: things and so it is no wonder we are not communicating.  What you are
: really concerned about here is that the _private_ section of a child
: has access to the _private_ section of the parent (and the visible
: part too, of course).  If GNAT is allowing the _visible_ part of the
: child access to the private part of the parent (and that child is NOT
: a private child), then GNAT is broken.  Report the bug.

Oh ok.  I'm relatively sure that the body of the child (public
stuff) was able to access the private goodies of the parent.
I will however do this again to make 100% sure and report it as
a bug if this is the case.  Thanks.



: A child is really an extension of the declarative region of the
: parent.  Some people (as you indicate for yourself) have voiced
: concerns about this.  For myself, I see it as simply a case of
: recognizing what is happening and being appropriately careful.

Right.  I like data abstraction and hiding what doesn't need
to be shared so I get a little edgy if I enter a scenario
where I have to expose more of my implementation than I have
to.


: Another point that may be confusing you is that "private" in Ada is
: really the analogue of "protected" in C++.  The "private" of C++ is
: achieved by use of package _bodies_ (which have no analogue in C++)

Ok this is a new one.  I was under the impression that package
bodies were the equivalent of public.  I mean if you put stuff
in package bodies then that stuff becomes available to 
any module that withs that package, or have I missed something
again?



: > Well yes I know of the above, again I'm being vague.  I meant
: > that the child package could see the parent package's private
: > goodies, not that the child package would make the parent's
: > private goodies available to whatever package with'ed it. 

: But _only_ the _private_ section of the child can see these private
: goodies of the parent.  So the visible part of the child has no more
: access to the private section of the parent than a standard client.

Ok, then it is a possible bug. Again I'll make 100% sure.  Don't
want to waste the time of the GNAT folks by reporting bogus
bugs :).


: > Well I knew about the above so I believe I'm relatively clear
: > on the visibility rules.  What was troubling me was that the
: > way I was doing it was making all of my parent's private stuff
: > visible to the child, rather than finding a way to just access
: > the one member I wanted in question.  Of course I could try
: > returning a pointer to the internal aliased type and indirectly
: > manipulate it through there, but the thing would be clumsy and
: > once again it wouldn't change having to deal with the child
: > package (unless I wanted this to be available to all!).

: OK, I know you have some concerns about this, but it is not clear
: what they are or more to the point why you have them.  I also don't
: understand what you mean by this phrase "available to all".  To "all"
: what"?

Well my concerns revolve around revealing more of my implementation
than I absolutely have to.  I mean if I want to share a data item
then I'll do so only if I determine that there is no other 
practical way of doing so, and then I'll try to restrict sharing
as much as possible.  I'm pretty sold on the concept of information
hiding.  As for "available to all", I meant visible to any module
that withs it.  So with returning pointers to the internal type
I'd end up making it "public" if you will so that even non-child
packages can get a hold of it, and that's something that is
worrying me as well.

[Snip]


: > Now with Ada you have the private section of a package.
: > This makes everything private but child packages can see
: > into this.  The problem is that if you use child packages
: > the children can see EVERYTHING.

: Yes, just like in C++ any child can see ALL the "protected" stuff.
: If you want the _C++_ private bit, too, put the definitions in the
: _body_.  Then they are _only_ visible there and no where else!
: Another route that is more flexible (but pays for it by letting in
: more possible "seers") is to use a _private_ child package.

Ok, let me make sure that I'm on the same wavelength so to speak.
What you mean is something like this:

package A is
	type Data_Type is ... -- This is "private"????

	...

	private  -- Everything from here until the end is protected
end A;

Is this correct?  If so then it seems to contradict what I've been
seeing.  Anything I dump in the non-private part of a package has
always been public.



: > that the output is double buffered.  Naturally to share
: > the screen items need to be able to access the current
: > buffer.

: This sounds like a classic shared resource

: Suggestion: Capture it with a protected type.

By protected type you mean the protected task right?  Isn't that
a bit of overkill?



: > Now the box class has an access to the buffer
: > so it can modify it (via alias), but of course to be able
: > to write to the same screen children need to be able
: > to get a hold of this buffer since they want to do more
: > with it.  Ie: the next child is a textbox so it needs
: > to put text in the box and it needs to get the buffer
: > to do this.

: Definitely use a protected type.  This is off topic from your concern
: about C++ style "private"/"protected" stuff, but it will make your
: current problem evaporate.  Egads, note too, that "protected type" in
: Ada has nothing to do with "protected" in C++.

Right, you mean protected as in the protected task type eh?


: > mess such a function would have to be made public

: Why???

Ok well a bit of snipping occurred so I can't quite recall the
context in which I made the above statement. I believe it was
with regards to returning the pointer in which case it would
be made public so I can avoid the child package entirely (and
hence the data sharing).



: package P is
:     type A is tagged private;
:     ...
: private
:     type A is tagged ...
:     ...
:     protected Buffer is
:         function Get...
:         entry Put....
:     private
:         The_Buffer : ... I guess something to do with A...
:     end Buffer;
: end P;

Interesting but there are a few problems.  The first is that
my box class is supposed to be able to support multiple
screens (virtual screens), which is why I encapsulated the
buffer alias in the type.  That way we could have different
screens with boxes and the like (like intros and so forth).
The way Buffer is now, it's only one screen for every
instance.  We could make a type of Buffer and declare instances
of it but then that brings us back to the problem, which we
still have here -- A is visible to the children.  This is
something we can't get around is it?  It looks like I will
have to deal with this fact.


: Only children can see Buffer and ONLY in their private section or
: bodies.  Buffer is _NOT_ public.  More over, The_Buffer is not even
: visible to the children or even the other things in P!  It is ONLY
: visible in the body of Buffer.

But the other data items of A are visible so that's still a
problem.


: > Messed up isn't it?  Maybe my whole concept of how
: > I'm doing this is flawed, but still am I right in
: > assuming that there is nothing equivalent to
: > C++'s protected type?  

: Absolutely not.  The equivalent is Ada private section definitions.

Well yes if one uses child classes.  Maybe I just need to get a
good book that deals specifically with Ada95's OOP features and
that talks some more about visibility. 

: /Jon
: -- 
: Jon Anthony
: Organon Motives, Inc.
: 1 Williston Road, Suite 4
: Belmont, MA 02178

: 617.484.3383
: jsa@organon.com


Thanks a million for your help!


--
Spasmo
"Everyone has secrets, but sometimes you get caught,
 So if it's just between us, my silence can be bought"
	"Blackmail" by Sloppy Seconds





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

* Re: Another OOP Question
  1996-08-21  0:00 Spasmo
@ 1996-08-22  0:00 ` Jon S Anthony
  0 siblings, 0 replies; 8+ messages in thread
From: Jon S Anthony @ 1996-08-22  0:00 UTC (permalink / raw)



In article <4velfg$asc@Masala.CC.UH.EDU> cosc19z5@Bayou.UH.EDU (Spasmo) writes:

> : Yes, I'm sure.  But the problem is we are talking about different
> : things and so it is no wonder we are not communicating.  What you are
> : really concerned about here is that the _private_ section of a child
> : has access to the _private_ section of the parent (and the visible
> : part too, of course).  If GNAT is allowing the _visible_ part of the
> : child access to the private part of the parent (and that child is NOT
> : a private child), then GNAT is broken.  Report the bug.
> 
> Oh ok.  I'm relatively sure that the body of the child (public
> stuff) was able to access the private goodies of the parent.
> I will however do this again to make 100% sure and report it as
> a bug if this is the case.  Thanks.

Careful.  The _body_ of child is definitely NOT public in any respect
and it definitely SHOULD be able to access the private section of any
parent.


> Right.  I like data abstraction and hiding what doesn't need
> to be shared so I get a little edgy if I enter a scenario
> where I have to expose more of my implementation than I have
> to.

Expose to what?  Do you think the impl itself is exposing itself to
itself and so you are "edgy" about this?  Probably not.  The relevant
thing is not to expose "detail" outside properly delineated scopes.
Clearly the "detail" has to go _somewhere_.


> : Another point that may be confusing you is that "private" in Ada is
> : really the analogue of "protected" in C++.  The "private" of C++ is
> : achieved by use of package _bodies_ (which have no analogue in C++)
> 
> Ok this is a new one.  I was under the impression that package
> bodies were the equivalent of public.  I mean if you put stuff
> in package bodies then that stuff becomes available to 
> any module that withs that package, or have I missed something
> again?

You have definitely missed something.  You are missing the entire
difference between _interfaces_ (package specifications) and
_implementations_ (package _bodies_).  Absolutely nothing outside the
body (and any separates which are semantically the same as being in
the body) can see anything in the body:

package P is
--
-- This is the spec.  Stuff in here up to the private section
-- is PUBLIC.  It is the stuff in this section that is visible to
-- clients that "with p".
...
private
--
-- Stuff here to the end is like C++ protected - No client can see it
-- (anything that states "with P" does not see this).
--
-- But the impl of P (P's body), private children, and the private
-- sections and bodies of children of P _can_ see this stuff.
...
end P;

package BODY P is
--
-- Goofy caps for emphasis.
-- This is _invisible_ to _all_ other constructs.  No children (not
-- even private children) can see anything in here.  It is completely
-- walled off.
...
end P;


> : But _only_ the _private_ section of the child can see these private
> : goodies of the parent.  So the visible part of the child has no more
> : access to the private section of the parent than a standard client.
> 
> Ok, then it is a possible bug. Again I'll make 100% sure.  Don't
> want to waste the time of the GNAT folks by reporting bogus
> bugs :).

I don't think there is a bug, but a misunderstanding.  The context for
what I wrote here is that of the child's _specification_.  NOT its body,
which _definitely_ does and should have access to any ancestor's private
section.


> : OK, I know you have some concerns about this, but it is not clear
> : what they are or more to the point why you have them.  I also don't
> : understand what you mean by this phrase "available to all".  To "all"
> : what"?
> 
> Well my concerns revolve around revealing more of my implementation
> than I absolutely have to.  I mean if I want to share a data item

I think the problem here is that you are not clear on the visibility
rules yet.  At least (especially) wrt package bodies.


> hiding.  As for "available to all", I meant visible to any module
> that withs it. 

As noted above, the only stuff so visible is the PUBLIC part of a
package SPECIFICATION.  Nothing in the private section is visible to
such clients.  Nothing in the body is visible to anything.


> : Yes, just like in C++ any child can see ALL the "protected" stuff.
> : If you want the _C++_ private bit, too, put the definitions in the
> : _body_.  Then they are _only_ visible there and no where else!
> : Another route that is more flexible (but pays for it by letting in
> : more possible "seers") is to use a _private_ child package.
> 
> Ok, let me make sure that I'm on the same wavelength so to speak.
> What you mean is something like this:
> 
> package A is
> 	type Data_Type is ... -- This is "private"????

Nope.  As written, Data_Type is PUBLIC.  But this is clearly NOT A's
_body_!  Tbe "body" issue appears to be the source of your confusion.


> 	...
> 
> 	private  -- Everything from here until the end is protected
> end A;

Casting into C++ terms, basically, yes.


> seeing.  Anything I dump in the non-private part of a package has
> always been public.

Exactly.  What you miss is:

package body A is
    type Data_Type is ... -- This is 100% private to the body of A
...
end A;

Note the _BODY_ bit!!  You can put all sorts of stuff in the body, not
just the impls of the public operations defined in the _specification_.


> : Suggestion: Capture it with a protected type.
> 
> By protected type you mean the protected task right?  Isn't that
> a bit of overkill?

No, I mean a protected type.  This is a passive concurrency construct.
A task is an active concurrency construct.  A protected type is
extremely efficient and in no way overkill for this sort of situation.
I believe you may have some tasks running around here (based on
previous posts asking about them) and in that case a protected type
for the shared screen is very likely what you want.  You certainly
can't have it be an unprotected shared resource or you will be back
here wondering why your program is acting goofy!


> : > mess such a function would have to be made public
> 
> : Why???
> 
> Ok well a bit of snipping occurred so I can't quite recall the
> context in which I made the above statement. I believe it was
> with regards to returning the pointer in which case it would
> be made public so I can avoid the child package entirely (and
> hence the data sharing).

The question concerned why do you think such a function would need to
be _public_?  If it is not something you want a client to see, put it
in the private section (if you think a child might want to see it -
"protected") or body (if you don't want anything else to see it - C++
private).


> : package P is
> :     type A is tagged private;
> :     ...
> : private
> :     type A is tagged ...
> :     ...
> :     protected Buffer is
> :         function Get...
> :         entry Put....
> :     private
> :         The_Buffer : ... I guess something to do with A...
> :     end Buffer;
> : end P;
> 
> Interesting but there are a few problems.  The first is that
> my box class is supposed to be able to support multiple
> screens (virtual screens), which is why I encapsulated the
> buffer alias in the type.

No problem.  Make Buffer a _type_ and instantiate for each screen:

package P is
    type A is tagged private;
...
private
    type A is tagged...
...
    protected type Screen_Type is
        function Get...
        entry    Put...
        ...
    private
        The_Buffer : ....
        ....
    end Screen_Type;
...
end P;

The type Screen_Type is only visible in the places where the _object_
Buffer was visible (P's body, private section or body of a P child or
in a private child anywhere).  The_Buffer is only visible in the body
of Screen_Type (Note also that The_Buffer acts as an "instance
variable" and there is such a variable for any instance of
Screen_Type).  Now somewhere later in any of those places (in a
private section of a child or P's body or a child body or private
child) we can write:

    Screen_1 : Screen_Type;
    Screen_2 : Screen_Type;

And when you wish access you write:

    Screen_1.Get(....);  -- Accesses Screen_1.The_Buffer
    ...
    Screen_1.Put(....);  -- Accesses Screen_2.The_Buffer


And somewhere else you can have a Screen_3 or an _array_ of screens or
dynamically allocate a _list_ of screens or whatever.


> The way Buffer is now, it's only one screen for every
> instance.  We could make a type of Buffer and declare instances
> of it but then that brings us back to the problem, which we
> still have here -- A is visible to the children.  This is
> something we can't get around is it?  It looks like I will
> have to deal with this fact.

No, this is no problem at all.  See above...


> : Only children can see Buffer and ONLY in their private section or
> : bodies.  Buffer is _NOT_ public.  More over, The_Buffer is not even
> : visible to the children or even the other things in P!  It is ONLY
> : visible in the body of Buffer.
> 
> But the other data items of A are visible so that's still a
> problem.

Well, it is only a problem if you don't do something about it.
Depending on what you need to do, put the definition of A in the body
of P or put it in a subpackage in the private section of P or...
There are several options.  What you can't do is declare A and then
for fear of ever revealing anything about it _anywhere_, never define
it.


> Well yes if one uses child classes.  Maybe I just need to get a
> good book that deals specifically with Ada95's OOP features and
> that talks some more about visibility. 

Actually Barnes covers this very succinctly and even gives a kind of
cookbook synopsis in the Rationale.  Probably does the same in his
Programming in Ada95.

I think your current hurdle is just the issue of the difference between
the specification and the body of a package (and probably task and
proctected type).  When you see it, you'll prolly say "Gee, how did
I not see this before?!"  :-)


/Jon
-- 
Jon Anthony
Organon Motives, Inc.
1 Williston Road, Suite 4
Belmont, MA 02178

617.484.3383
jsa@organon.com





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

end of thread, other threads:[~1996-08-22  0:00 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1996-08-21  0:00 Another OOP Question Spasmo
  -- strict thread matches above, loose matches on Subject: below --
1996-08-21  0:00 Spasmo
1996-08-22  0:00 ` Jon S Anthony
1996-08-20  0:00 Spasmo
1996-08-20  0:00 ` Jon S Anthony
1996-08-20  0:00   ` Robert I. Eachus
1996-08-18  0:00 Spasmo
1996-08-19  0:00 ` Jon S Anthony

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