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.3 required=5.0 tests=BAYES_00,INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: fac41,8ff80a74f45b5cd3 X-Google-Attributes: gidfac41,public X-Google-Thread: 103376,8ff80a74f45b5cd3 X-Google-Attributes: gid103376,public From: dnew@zloty.fv.com (Darren New) Subject: Re: Visibility and access to "public" attributes Date: 1997/08/30 Message-ID: <5u7pqa$3es@newshub.atmnet.net>#1/1 X-Deja-AN: 269006169 References: <872885107.17682@dejanews.com> Organization: FIRST VIRTUAL Holdings Inc. Newsgroups: comp.lang.ada,comp.lang.eiffel Date: 1997-08-30T00:00:00+00:00 List-Id: In article <872885107.17682@dejanews.com>, wrote: >The issue I'm raising here is the ability of a client to >depend on a class' attribute (feature). To expand on the >Aircraft example a bit (pardon my Eiffel- I don't write the >langauge fluenty; I'm just a tourist! ;) ) > >class AIRCRAFT > Take_Off; -- I don't know how you write methods in Eiffel! >feature > > Propeller_RPM: Integer; > >end > >Now, suppose you change the AIRCRAFT class to have jet engines and >thus remove or change the Propeller_RPM attribute? Suppose you decide you have a kind of airplane that can't Take_Off? > Because it was >*visible*, someone may have written code to read it and now if you >change the spec of the class their code will break. It doesn't >matter that they can't update the attribute! If they can refer to it >at all and you remove the attribute from the class definition, their >code is broken! Don't make it public if you're not going to support it. Exactly the same argument could be make for the Take_Off procedure. What if you had another function called "Is_Flying". What if that was stored as a boolean variable? What if it was actually a boolen function? Why should the client need to know the difference between the two? > In this case, the only way to avoid breaking client >code written for the original definition of AIRCRAFT would be to >add a useless Propeller_RPM accessor that returns zero or something. Again, you can say the same for "Take_Off." >In this case, the AIRCRAFT class' features/attributes would have been >better off hidden, since the Take_Off method's interface didn't >change when the Propeller_RPM attribute was changed/removed. If you wrote a program that relied on knowing the Propeller_RPM (say, a flight simulator sound module, or a cockpit display instrument), then yes, it'll break when you no longer have propellers. Is that suprising? >That's the issue I'm writing about: impact on client code. When >in Eiffel would you want to allow a client to be dependent on a >type's implementation in this way? Ah, there's the rub. The "Propeller_RPM" isn't part of the implementation. It's part of the specification. You're saying that the clients can query the Propeller_RPM and see an INTEGER. If that's 100% implementation, then hide it. If it's something clients need to do, then you can't hide it *or* remove it. >Now to Pat's question: > >>What I'd like to know is, how do you decide in Ada whether >>to make an attribute public, and thus irrevocably commit to >>allowing clients to assign to it? > >Personally, I only do this for types which cannot be put in an >invalid state by the client setting the attributes, e.g. Yup. In Eiffel, you would have a "set_rpm" procedure to set the value, and the preconditions would tell you what the valid values are, and the postconditions would say that the new value of "rpm" is the same as the argument to "set_rpm". This jibes, because in Eiffel you should have functions that return values but don't make changes, and procedures which make changed but don't return values. >Now, if I had a type with more complex methods >and it was possible for a user-adjusted attribute to put the >object into an inconsistent state, then I would make its >attributes private and the attributes would be set only by >higher-level methods. That is, I wouldn't provide a low-level >accessor to set an attribute if doing so could allow the object >to be put into an invalid state. And that's the same in Eiffel. Or you can use preconditions on your set functions if the conditions for validity are simple enough, like "0 <= rpm and rpm <= 10000" or something. For truely complex conditions (like "the directed graph cannot have cycles") then you need functions to set the value, yes. So where's the problem? :-) --- Darren