From 79ca29659a46c87aaf2f036bcd6ccbbc07332e23 Mon Sep 17 00:00:00 2001 From: halw Date: Mon, 18 May 2009 21:14:08 +0000 Subject: [PATCH] Author:halw Date:2009-05-18T21:14:08.000000Z git-svn-id: https://svn.eiffel.com/eiffel-org/trunk@219 abb3cda0-5349-4a8f-a601-0c33ac3a8c38 --- .../creating-new-void-safe-project.wiki | 69 ++++++++++++++++++- ...afety-background-definition-and-tools.wiki | 2 +- 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/documentation/current/method/void-safe-programming-eiffel/creating-new-void-safe-project.wiki b/documentation/current/method/void-safe-programming-eiffel/creating-new-void-safe-project.wiki index 078ac177..305181aa 100644 --- a/documentation/current/method/void-safe-programming-eiffel/creating-new-void-safe-project.wiki +++ b/documentation/current/method/void-safe-programming-eiffel/creating-new-void-safe-project.wiki @@ -150,14 +150,79 @@ feature -- Access feature {NONE} -- Implementation - descriptive_text_cache: like descriptive_text + descriptive_text_cache: like descriptive_text +This example will not compile in a void-safe project (assuming types are attached by default). The problem is that the attribute descriptive_text_cache is of an attached type, therefore will be flagged by the compiler as not properly set (VEVI). Of course, it will be ... that's the whole idea here: not to initialize descriptive_text_cache until it's actually used. So it sounds like descriptive_text_cache should be declared detachable. That is: + + descriptive_text_cache: detachable like descriptive_text + +This change will make this routine compile in a void-safe project. But you should notice that there is a ripple-down effect due to the change. Within the routine, l_result is typed like descriptive_text_cache, so it also will be detachable. Therefore we might expect trouble, because later in the routine we have: + + Result := l_result + +Because we know Result is attached and l_result is detachable, we might expect a compiler error in which the source of an assignment does not conform to its target (VJAR). + +But we don't get such an error. The reason is two-fold. First, l_result is a local variable whose use can be protected by a CAP. Second, the CAP in this case is the check to ensure that l_result is not void. We only make the assignment to Result if l_result is not void. So the compiler can prove that l_result cannot be void at the point at which the assignment occurs ... therefore, no error. + +Because the '''attached syntax''' can test attached status and provide a local variable, it can be used to remove some unnecessary code from this routine. The version of the routine that follows shows the attached syntax being used to test the attached status of descriptive_text_cache and yield the local variable l_result in the case that descriptive_text_cache is indeed attached. + + descriptive_text: STRING + do + if attached descriptive_text_cache as l_result then + Result := l_result + else + create Result.make_empty + descriptive_text_cache := Result + end + ensure + result_attached: Result /= Void + result_not_empty: not Result.is_empty + result_consistent: Result = descriptive_text + end + - ===As a replacement for assignment attempt=== +The assignment attempt ( ?= ) has traditionally been used to deal with external objects (e.g., persistent objects from files and databases) and to narrow the type of an object in order to use more specific features. The latter is a process known by names such as "down casting" in some technological circles. A classic example is doing specific processing on some elements of a polymorphic data structure. Let's look at an example. Suppose we have a LIST of items of type POLYGON: + + my_polygons: LIST [POLYGON] + +POLYGONs could be of many specific types, and one of those could be RECTANGLE. Suppose too that we want to print the measurements of the diagonals of all the RECTANGLEs in the list. Class RECTANGLE might have a query diagonal returning such a measurement, but POLYGON would not, for the reason that the concept of diagonal is not meaningful for all POLYGONs, e.g., TRIANGLEs. + +As we traverse the list we would use assignment attempt to try to attach each POLYGON to a variable typed as RECTANGLE. If successful, we can print the result of the application of diagonal. + + l_my_rectangle: RECTANGLE + + ... + from + my_polygons.start + until + my_polygons.exhausted + loop + l_my_rectangle ?= my_polygons.item + if l_my_rectangle /= Void then + print (l_my_rectangle.diagonal) + print ("%N") + end + end + +The '''attached syntax''' allows us to check both attached status and type, and provides us with a fresh local variable when appropriate: + + from + my_polygons.start + until + my_polygons.exhausted + loop + if attached {RECTANGLE} my_polygons.item as l_my_rectangle then + print (l_my_rectangle.diagonal) + print ("%N") + end + end + +As with the other examples of the '''attached syntax''', it is no longer necessary to make a declaration for the local variable, in this case l_my_rectangle. + ==More about CAPs== 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 f814430b..61730967 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 @@ -200,7 +200,7 @@ where x is the formal argument for r, then if x is of ===Stable attributes=== -Stable attributes are really stable detachable attributes, as adding the concept of stability is meaningful only for detachable attributes. Declaring a detachable attribute as stable, means that it behaves like a detachable attribute except that its assignment rules mimic those of attached attributes. In other words, a stable attribute can never be the target of an assignment in which the source is Void or a detachable type. +Stable attributes are really stable ''detachable'' attributes, as adding the concept of stability is meaningful only for detachable attributes. Declaring a detachable attribute as stable, means that it behaves like a detachable attribute except that its assignment rules mimic those of attached attributes. In other words, a stable attribute can never be the target of an assignment in which the source is Void or a detachable type. test: detachable TEST note