From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, T_FILL_THIS_FORM_SHORT autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,c35d69ccf1ab6b78 X-Google-Attributes: gid103376,public From: jsa@alexandria (Jon S Anthony) Subject: Re: Another OOP Question Date: 1996/08/22 Message-ID: X-Deja-AN: 175710985 sender: news@organon.com (news) references: <4velfg$asc@Masala.CC.UH.EDU> organization: Organon Motives, Inc. newsgroups: comp.lang.ada Date: 1996-08-22T00:00:00+00:00 List-Id: 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