Author:halw

Date:2009-10-23T19:43:48.000000Z


git-svn-id: https://svn.eiffel.com/eiffel-org/trunk@337 abb3cda0-5349-4a8f-a601-0c33ac3a8c38
This commit is contained in:
halw
2009-10-23 19:43:48 +00:00
parent 9502f2ac67
commit 9655baf934
2 changed files with 31 additions and 7 deletions

View File

@@ -16,11 +16,11 @@ Such a feature call is judged acceptable at compile time only if the type of <co
In statically typed languages like Eiffel, the compiler guarantees that you cannot, at run time, have a situation in which feature <code>f</code> is not applicable to the object attached to <code>x</code>. 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 <code>f</code> that can be applied at run time to <code>x</code> in the example above. But it does not assure us that, in the case in which <code>x</code> is a reference, that there will always be an object attached to <code>x</code> at any time <code>x.f (a)</code> 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
<code>
my_test: detachable TEST
note
options: stable
option: stable
attribute
end
</code>

View File

@@ -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:
<code>
my_stable_string: detachable STRING
note
option: stable
attribute
end
</code>
The detachable attribute <code>my_stable_string</code>, 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, <code>my_stable_string</code> can be initialized later during the instance's life-cycle or not at all. But because it is detachable, <code>my_stable_string</code> 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:
<code>
if my_stable_string /= Void then
my_stable_string.append ("abc") -- Valid
...
</code>
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 <code>Void</code> or some expression which could possibly be void.
@@ -70,15 +92,18 @@ So, for a local variable <code>l_string</code>, the following is valid:
l_string: detachable STRING
do
if l_string /= Void then
l_string.append ("xyz") -- Valid
l_string.append ("abc") -- Valid
...
</code>
But, if <code>l_string</code> had been a target of an assignment in which the source could possibly have been void, then it could no longer be guaranteed that <code>l_string</code> is non-void. So, assuming that <code>my_detachable_string</code> is an attribute declared as type <code>detachable STRING</code>, the code in this example would be invalid:
But, if <code>l_string</code> had been a target of an assignment in which the source could possibly have been void, then it could no longer be guaranteed that <code>l_string</code> is non-void. So, assuming that <code>my_detachable_string</code> is an attribute declared as type <code>detachable STRING</code>, the second application of <code>append</code> in this example would be invalid:
<code>
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 <code>l_string</code> had been a target of an assignment in which the so