mirror of
https://github.com/EiffelSoftware/eiffel-org.git
synced 2025-12-06 14:52:03 +01:00
Author:halw
Date:2009-05-15T23:45:14.000000Z git-svn-id: https://svn.eiffel.com/eiffel-org/trunk@217 abb3cda0-5349-4a8f-a601-0c33ac3a8c38
This commit is contained in:
@@ -111,7 +111,7 @@ Let's look at some specific cases and how fixing them unfolds.
|
||||
[[Image:VoidSafeVEVI1]]
|
||||
|
||||
|
||||
There are two errors like this in our legacy system. They are probably the most obvious and easiest cases to handle.
|
||||
There are two VEVI errors like this in class <code>APPLICATION</code> our legacy system. They are probably the most obvious and easiest cases to handle.
|
||||
|
||||
<code>
|
||||
feature {NONE} -- Initialization
|
||||
@@ -137,7 +137,7 @@ Here attribute declarations for <code>my_nvp</code> and <code>my_nvp_list</code>
|
||||
make
|
||||
-- Run application.
|
||||
do
|
||||
create my_nvp.make ("Hello", "World")
|
||||
create my_nvp.make ("SomeName", "SomeValue")
|
||||
create my_nvp_list.make
|
||||
...
|
||||
end
|
||||
|
||||
@@ -62,10 +62,61 @@ During a period of transition, there will be different Eiffel configuration file
|
||||
|
||||
The keyword <code>attribute</code> is should be used with some care. You might be tempted to think that it would be convenient or add an extra element of safety to use self-initializing attributes widely. And in a way, you would be correct. But you should also understand that there is a price to pay for using self-initializing attributes and stable attributes. It is that upon every access, an evaluation of the state of the attribute must be made. So, as a general rule, you should avoid using self-initializing attributes only for the purpose of lazy initialization.
|
||||
|
||||
==More about CAPs==
|
||||
|
||||
==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:
|
||||
<code>
|
||||
if x /= Void then
|
||||
-- ... Any other instructions here that do not assign to x
|
||||
x.f (a)
|
||||
end
|
||||
</code>
|
||||
|
||||
is a CAP for <code>x</code> ... but that's only true if <code>x</code> is a local variable or a formal argument to the routine that contains the code.
|
||||
|
||||
So access a detachable attribute safely, we could declare a local variable, make an assignment, and test for <code>Void</code> as above. Something like this:
|
||||
<code>
|
||||
my_detachable_attribute: detachable MY_TYPE
|
||||
|
||||
...
|
||||
some_routine
|
||||
local
|
||||
x: like my_detachable_attribute
|
||||
do
|
||||
x := my_detachable_attribute
|
||||
if x /= Void then
|
||||
-- ... Any other instructions here that do not assign to x
|
||||
x.f (a)
|
||||
end
|
||||
...
|
||||
</code>
|
||||
The attached syntax can both check the attached status of a detachable attribute and also provide a new local variable. So the routine becomes:
|
||||
<code>
|
||||
some_routine
|
||||
do
|
||||
if attached my_detachable_attribute as x then
|
||||
-- ... Any other instructions here that do not assign to x
|
||||
x.f (a)
|
||||
end
|
||||
...
|
||||
</code>
|
||||
|
||||
|
||||
In its simplest form, the attached syntax can be used to test attached status only:
|
||||
<code>
|
||||
if attached x then
|
||||
do_something
|
||||
else
|
||||
do_something_different
|
||||
end
|
||||
</code>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
==More about CAPs==
|
||||
|
||||
==Stable attributes==
|
||||
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ By using the '''attached syntax''', we can perform an '''object test''' on a var
|
||||
l_x.f (a)
|
||||
end
|
||||
</code>
|
||||
In the example above, <code>x</code> is tested to make certain that it is attached. If so, the local <code>l_x</code> is attached to the same object as <code>x</code> and can be used safely even if <code>x</code> is a class attribute. So, the attached syntax, is really another CAP, because it provides a clearly verifiable place for the application of features to targets that are guaranteed not to be void.
|
||||
In the example above, <code>x</code> is tested to make certain that it is attached. If so, the new local <code>l_x</code> becomes attached to the same object as <code>x</code>. And so the object can be used safely even if <code>x</code> is a class attribute. So, the attached syntax, is really another CAP, because it provides a clearly verifiable place for the application of features to targets that are guaranteed not to be void.
|
||||
|
||||
|
||||
{{note|The attached syntax has other syntax variations as well as other uses. These will be discussed later. }}
|
||||
@@ -162,11 +162,13 @@ Still, it's not too hard to understand the basics of initializing variables of a
|
||||
end
|
||||
</code>
|
||||
|
||||
* A variable is considered properly set if it is '''self-initializing'''. What it means to be self-initializing is explained [[Void-safe programming in Eiffel#Self-initializing variables|below]].
|
||||
* A variable is considered properly set if it is '''self-initializing'''. What it means to be self-initializing is explained below.
|
||||
|
||||
===Self-initializing attributes===
|
||||
|
||||
A self-initializing attribute is guaranteed to have a value when accessed at run time. Declarations of self-initializing attributes are characterized by the use of <code>attribute</code> keyword. The code that follows the <code>attribute</code> keyword is executed to initialize the attribute in the case that the attribute is accessed prior to being initialized in any other way. So, the code in the attribute part is a kind of last resort for initialization.
|
||||
A self-initializing attribute is guaranteed to have a value when accessed at run time. Declarations of self-initializing attributes are characterized by the use of <code>attribute</code> keyword. The code that follows the <code>attribute</code> keyword is executed to initialize the attribute in the case that the attribute is accessed prior to being initialized in any other way.
|
||||
|
||||
So, self-initializing attributes are just ordinary attributes, and they can be initialized in the traditional ways. The difference is that the code in the attribute part serves as a kind of safety net guaranteeing that a self-initializing attribute will never be void.
|
||||
|
||||
<code>
|
||||
value: STRING
|
||||
|
||||
Reference in New Issue
Block a user