Xref: utzoo comp.object:1488 comp.lang.eiffel:1015 Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!sdd.hp.com!ucsd!hub.ucsb.edu!eiffel!bertrand From: bertrand@eiffel.UUCP (Bertrand Meyer) Newsgroups: comp.object,comp.lang.eiffel Subject: Re: Should a constructor do "work"? Summary: Get the invariant right Message-ID: <372@eiffel.UUCP> Date: 19 Jul 90 15:58:23 GMT References: <55236@microsoft.UUCP> Organization: Interactive Software Engineering, Santa Barbara CA Lines: 59 In , wex@dali.pws.bull.com (Alan Wexelblat?) questions my previous suggestion that >> If invariants are checked and a creation operation raises >> an exception, the target of the Create should remain void, >> excluding any creation of an inconsistent object. by stating > (...) Suppose then that some of the initialization fails. Can't I write a > specification that says "the value will be a list of numbers or NULL"? Then > when the initialization fails, I can return an object with that particular > slot having a NULL value. > > This would fulfill the specification; are you saying that this would not > "raise an exception" in the sense that you mean it above? But this is precisely the point. The invariant is here to state the specification. If ``null'' is an acceptable value, then the invariant should say so and there is no reason to pass an exception to the client. Otherwise the invariant is unsatisfiable and there should be an exception. To make this concrete, take the example of an Eiffel class with two attributes: n: INTEGER; l: LIST [STOCK] and assume we expect that the creation will initialize `n', perhaps from an argument to the creation operation, and allocate list `l' with a number of elements equal to `n'. Furthermore, the length of the list should remain equal to `n' during the lifetime of the object. Then the invariant clause for the class will say invariant l.count = n (`count' is the standard name used in the Eiffel libraries for the number of meaningful elements in a data structure.) In this case, if the creation operation fails to ensure the invariant (for example because there is no memory left to allocate `n' list elements for the requested `n'), then it would be improper and dangerous to create an inconsistent instance of the class. If, however, the class designer is prepared to deal with such objects, he may easily adapt the invariant clause to read (for example): invariant l.empty or else l.count = n In which case there is no ``failure'' visible to the outside world. No inconsistent object has been created. Assume for example that -- Bertrand Meyer bertrand@eiffel.com