mirror of
https://github.com/EiffelSoftware/eiffel-org.git
synced 2025-12-06 14:52:03 +01:00
Author:halw
Date:2009-05-17T21:20:21.000000Z git-svn-id: https://svn.eiffel.com/eiffel-org/trunk@218 abb3cda0-5349-4a8f-a601-0c33ac3a8c38
This commit is contained in:
@@ -49,7 +49,7 @@ Here's an example of the kind of error you might expect when compiling with full
|
||||
[[Image:VGCC error]]
|
||||
|
||||
|
||||
The situation here is that the feature <code>split</code> has been inherited by our class <code>NVP_LIST</code>. Feature <code>split</code> includes code to create and attach feature <code>sublist</code> which is typed <code>attached like Current</code> which in this case means <code>attached NVP_LIST</code>. To do this creation, <code>split</code> uses a creation procedure <code>make_sublist</code>.
|
||||
The situation here is that the feature <code>split</code> has been inherited (from class <code>TWO_WAY_LIST [G]</code>) by our class <code>NVP_LIST</code>. Feature <code>split</code> includes code to create and attach feature <code>sublist</code> which is typed <code>attached like Current</code> which in this case means <code>attached NVP_LIST</code>. To do this creation, <code>split</code> uses a creation procedure <code>make_sublist</code>.
|
||||
|
||||
Now here's the rub: <code>NVP_LIST</code> has not named <code>make_sublist</code> as a creation procedure:
|
||||
<code>
|
||||
|
||||
@@ -64,7 +64,9 @@ The keyword <code>attribute</code> is should be used with some care. You might b
|
||||
|
||||
==More about the ''attached syntax''==
|
||||
|
||||
In the introduction to the attached syntax, we used an example which showed how the attached syntax is directly relevant to void-safety. The code:
|
||||
===As a CAP which yields a local variable===
|
||||
|
||||
In the introduction to the attached syntax, we used an example which showed how the attached syntax is directly relevant to void-safety. That is, the code:
|
||||
<code>
|
||||
if x /= Void then
|
||||
-- ... Any other instructions here that do not assign to x
|
||||
@@ -101,6 +103,7 @@ The attached syntax can both check the attached status of a detachable attribute
|
||||
...
|
||||
</code>
|
||||
|
||||
===As a test for attachment===
|
||||
|
||||
In its simplest form, the attached syntax can be used to test attached status only:
|
||||
<code>
|
||||
@@ -111,8 +114,49 @@ In its simplest form, the attached syntax can be used to test attached status on
|
||||
end
|
||||
</code>
|
||||
|
||||
So in this simple form, <code>attached x</code> can be used instead of <code>x /= Void</code>. The two are semantically equivalent, and which one you choose is a matter of personal preference.
|
||||
|
||||
|
||||
===As a tool for "once per object"===
|
||||
|
||||
There is a code pattern for functions that exists in some Eiffel software to effect "once-per-object / lazy evaluation".
|
||||
|
||||
{{note|This is different from an Eiffel <code>once</code> routine, which is "once-per-thread" or "once-per-process" depending upon how it is configured. }}
|
||||
|
||||
This "once-per-object" code pattern employs a cached value for some object which is not exported. When it is applied, the "once-per-object" function checks the attachment status of the cached value. If the cached value is void, then it is created and assigned to <code>Result</code>. If the cached value was found already to exist, then it is just assigned to <code>Result</code>.
|
||||
|
||||
Here's an example of this pattern used to produce some descriptive text of an instance of its class:
|
||||
|
||||
<code>
|
||||
feature -- Access
|
||||
|
||||
descriptive_text: STRING
|
||||
local
|
||||
l_result: like descriptive_text_cache
|
||||
do
|
||||
l_result := descriptive_text_cache
|
||||
if l_result = Void then
|
||||
create Result.make_empty
|
||||
-- ... Build Result with appropriate descriptive text for Current
|
||||
descriptive_text_cache := Result
|
||||
else
|
||||
Result := l_result
|
||||
end
|
||||
ensure
|
||||
result_attached: Result /= Void
|
||||
result_not_empty: not Result.is_empty
|
||||
result_consistent: Result = descriptive_text
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
descriptive_text_cache: like descriptive_text
|
||||
|
||||
</code>
|
||||
|
||||
|
||||
|
||||
===As a replacement for assignment attempt===
|
||||
|
||||
|
||||
==More about CAPs==
|
||||
|
||||
@@ -70,7 +70,7 @@ We know that in the context of certain code patterns, it is clear that it would
|
||||
Here a check is made to ensure <code>x</code> is not void. Then as long as no assignments to <code>x</code> are made in the interim, a feature <code>f</code> can be applied to <code>x</code> with the certainty that <code>x</code> will be attached at the time ... and importantly, this can be determined at compile time. So, we say that this code pattern is a CAP for <code>x</code>.
|
||||
|
||||
|
||||
It is important to understand that in this example (and with other CAPs), <code>x</code> is allowed to be a local variable or formal argument only. That is, <code>x</code> may not be an attribute or general expression. Direct access to class attribute references cannot allowed via a CAP due to the fact that they could be set to void by a routine call in some execution path invoked by the intervening instructions or possibly even different process thread.
|
||||
It is important to understand that in this example (and with other CAPs), <code>x</code> is allowed to be a local variable or formal argument only. That is, <code>x</code> may not be an attribute or general expression. Direct access to class attribute references cannot allowed via a CAP due to the fact that they could be set to void by a routine call in some execution path invoked by the intervening instructions or possibly even different process thread. In a later [[Void-safety: Background, definition, and tools#Types as "attached" or "detachable"|section]], we well see that this is not quite such a limitations as it may appear at this point.
|
||||
|
||||
|
||||
{{note|You will find a more detailed discussion of CAPs in [[Void-safe programming in Eiffel#More about CAPs|More about CAPs]]. The current list of CAPs appears in the [[Catalog of Certified Attachment Patterns]]. }}
|
||||
@@ -129,7 +129,8 @@ This doesn't mean that on every declaration you must put either an ''attached ma
|
||||
|
||||
In Eiffel then, all declarations will have types that are either '''attached''' or '''detachable'''.
|
||||
|
||||
This means that we need only use CAPs and the attached syntax with detachable types.
|
||||
This means that we need only use CAPs and the attached syntax with detachable types. So the important thing to remember is that ''direct access to class attributes of detachable types is never void-safe.''
|
||||
|
||||
|
||||
===Initialization rule===
|
||||
|
||||
|
||||
Reference in New Issue
Block a user