diff --git a/documentation/current/method/void-safe-programming-eiffel/void-safety-background-definition-and-tools.wiki b/documentation/current/method/void-safe-programming-eiffel/void-safety-background-definition-and-tools.wiki index 8856df42..20d6ac8d 100644 --- a/documentation/current/method/void-safe-programming-eiffel/void-safety-background-definition-and-tools.wiki +++ b/documentation/current/method/void-safe-programming-eiffel/void-safety-background-definition-and-tools.wiki @@ -16,11 +16,11 @@ Such a feature call is judged acceptable at compile time only if the type of f is not applicable to the object attached to x. If you've ever been a Smalltalk programmer, you are certainly familiar with this most common of errors that manifests itself as "Message not understood." It happens because Smalltalk is not statically typed. -==Non-void-safe software== +==Void-unsafe software== Static typing will ensure that there is some feature f that can be applied at run time to x in the example above. But it does not assure us that, in the case in which x is a reference, that there will always be an object attached to x at any time x.f (a) is executed. -This problem is not unique to Eiffel. Other environments that allow or mandate reference semantics also allow the possibility of non-void-safe run time errors. If you've worked in Java or .NET you may have seen the NullReferenceException. Sometimes you might have experienced this rather poetic sounding message: "Object reference not set to an instance of an object". In Eiffel you would see "Feature call on void target". All these are the hallmarks of run time errors resulting from non-void-safe software. +This problem is not unique to Eiffel. Other environments that allow or mandate reference semantics also allow the possibility of void-unsafe run time errors. If you've worked in Java or .NET you may have seen the NullReferenceException. Sometimes you might have experienced this rather poetic sounding message: "Object reference not set to an instance of an object". In Eiffel you would see "Feature call on void target". All these are the hallmarks of run time errors resulting from void-unsafe software. {{note|If you need a review of difference between reference types and expanded types in Eiffel, see [[ET: The Dynamic Structure: Execution Model|the chapter of the Eiffel Tutorial dedicated to the Eiffel execution model]]. }} @@ -200,7 +200,7 @@ Stable attributes are really stable ''detachable'' attributes, as adding the con my_test: detachable TEST note - options: stable + option: stable attribute end diff --git a/documentation/current/method/void-safe-programming-eiffel/what-makes-certified-attachment-pattern.wiki b/documentation/current/method/void-safe-programming-eiffel/what-makes-certified-attachment-pattern.wiki index dab2ccd0..950fc608 100644 --- a/documentation/current/method/void-safe-programming-eiffel/what-makes-certified-attachment-pattern.wiki +++ b/documentation/current/method/void-safe-programming-eiffel/what-makes-certified-attachment-pattern.wiki @@ -60,7 +60,29 @@ In the second context, the expression can be a '''read-only entity'''. Read-only Additionally, the Eiffel Software compiler allows for [[Void-safety: Background, definition, and tools#Stable attributes|stable attributes]] and local variables to be protected by a CAP. -Stable attributes are the only class attributes which are CAP-able. This is because stable attributes, once attached at run-time, can never have a void value again. +===Stable attributes=== + +Stable attributes are the only class attributes which are CAP-able. This is because stable attributes, once attached at run-time, can never have a void value again. So, you use stable attributes safely by using them under the protection of a CAP. Consider this stable attribute: + + my_stable_string: detachable STRING + note + option: stable + attribute + end + +The detachable attribute my_stable_string, because it is stable, is not required to be initialized during the creation of instances of the class in which it is a feature. That means that for each instance, my_stable_string can be initialized later during the instance's life-cycle or not at all. But because it is detachable, my_stable_string cannot be accessed in any context in which it cannot be determined that it is currently attached. For ordinary attributes, this means either using an object test and accessing the object through an object test local, or using using a local variable under the protection of a CAP. + +Stable attributes however, can be used directly in a CAP, as shown below: + + + if my_stable_string /= Void then + my_stable_string.append ("abc") -- Valid + ... + + +So using stable attributes can reduce the need to initialize rarely used attributes, and the need to code object tests. + +===Local variables=== Local variables can be used in a CAP as long as they are not the target of an assignment whose source is Void or some expression which could possibly be void. @@ -70,15 +92,18 @@ So, for a local variable l_string, the following is valid: l_string: detachable STRING do if l_string /= Void then - l_string.append ("xyz") -- Valid + l_string.append ("abc") -- Valid ... -But, if l_string had been a target of an assignment in which the source could possibly have been void, then it could no longer be guaranteed that l_string is non-void. So, assuming that my_detachable_string is an attribute declared as type detachable STRING, the code in this example would be invalid: + +But, if l_string had been a target of an assignment in which the source could possibly have been void, then it could no longer be guaranteed that l_string is non-void. So, assuming that my_detachable_string is an attribute declared as type detachable STRING, the second application of append in this example would be invalid: + local l_string: detachable STRING do if l_string /= Void then + l_string.append ("abc") -- Valid l_string := my_detachable_string l_string.append ("xyz") -- Invalid: my_detachable_string could be void ... @@ -86,4 +111,3 @@ But, if l_string had been a target of an assignment in which the so -