[[Property:modification_date|Mon, 25 Sep 2023 09:37:39 GMT]]
[[Property:publication_date|Mon, 25 Sep 2023 09:37:39 GMT]]
[[Property:title|Eiffel Class and Feature Names]]
[[Property:weight|2]]
[[Property:uuid|16e4a231-7aae-4b37-52fd-67876cc222ad]]
Certain naming conventions are respected by Eiffel programmers. Although Eiffel is not case-sensitive, convention dictates the use of upper and lower case in particular situations. When you program in Eiffel for .NET, you create new Eiffel classes, but you also use types from .NET assemblies. These .NET types are presented to you in a view that is consistent with Eiffel conventions.
==Eiffel Class Names==
Convention dictates that Eiffel class names are always all upper case characters with words separated by the underscore ("_") character. Eiffel classes are not qualified by "namespace" as in some other languages. This means that Eiffel class names must be unique with in a system. It also means that any types from existing .NET assemblies will have their names mapped to conventional Eiffel class names in order to be used by Eiffel classes in EiffelEnvision
Here are some class names and their descriptions from the Eiffel Base Library. These class names comply with the Eiffel class naming convention.
STRING
Sequences of characters, accessible through integer indices in a contiguous range.
RANDOM
Pseudo-random number sequence, linear congruential method.
ARRAYED_LIST
Lists implemented by resizable arrays.
LINKED_QUEUE
Unbounded queues implemented as linked lists.
Now here are some type names from the .NET mscorlib as they appear as conventional Eiffel class names (i.e. , in the form in which they become available to Eiffel for .NET programmers), followed by their full .NET type and their Summary from the .NET library. names.
SYSTEM_STRING
System.String
Represents an immutable series of characters.
SYSTEM_RANDOM
System.Random
Represents a pseudo-random number generator, a device that produces a sequence of numbers that meet certain statistical requirements for randomness.
ARRAY_LIST
System.Collections.ArrayList
Implements the System.Collections.IListinterface using an array whose size is dynamically increased as required.
SYSTEM_QUEUE
System.Collections.Queue
Represents a first-in, first-out collection of objects.
In summary, Eiffel class names and type names from .NET assemblies made available to Eiffel programmers will be all upper case, with words separated by the underscore character.
===Eiffel Names for .NET Types===
How Eiffel compliant names are derived from .NET type names is fairly simple in most cases. The "simple" class name, that is, the word following the rightmost dot in the full class name, is converted to an Eiffel compliant name by making it upper case and separating in embedded words by underscore. In the example above, System.Collection.ArrayList
becomes ARRAY_LIST
.
The other cases in the example are not quite so simple. If the basic derivation produces a name which conflicts with a classname in the Eiffel Base Library, then it will be disambiguated. The simple derivation of System.String would be STRING, but this would conflict with Eiffel's STRING class, so System.String becomes available to Eiffel for .NET programmers as SYSTEM_STRING.
Sometimes it is better to disambiguate an entire assembly rather than handling individual exceptions to the simple derivation. This is done by specifying a common prefix for all types in the assembly. For example, EiffelEnvision uses a prefix of " DATA_" for all classes in the .NET assembly System.Data. As a result, the type System.Data.Constraint is available in Eiffel as class DATA_CONSTRAINT.
You'll see a little more about namespaces, assemblies, and Eiffel clusters in [[Type Organization|Type Organization]] .
===Similar Types from Both Libraries===
You may have noticed a similarity in the names and descriptions from the Eiffel Base Library and those from the .NET "mscorlib" library. This is not by accident. The Eiffel class STRING
is a different class from the .NET type System.String
, which Eiffel programmers see represented as Eiffel class SYSTEM_STRING
. There is more on this subject in [[Similar Types Occurring in Both Libraries|Similar Types Occurring in Both Libraries]] .
==Eiffel Feature Names==
By convention, feature names in Eiffel use all lower case characters, and like class names, words are separated by underscore. Also as with class names, the names of members from .NET assemblies will be represented in a form that complies with the Eiffel convention.
Let's look at some simple examples. First some feature names from the Eiffel Base Library.
to_upper
From class STRING: Converts to upper case.
item_double
From class RANDOM: The current random number as a double between 0 and 1
Now check out these member names from the .NET "mscorlib" type library. These have been made available to Eiffel for .NET programmers in the Eiffel convention. Following the Eiffel name, you see their .NET member name and type name.
to_upper
Member ToUpper from typeSystem.String
Returns a new System.String with the same content as the target, except all upper case.
next_double
Member NextDouble from type System.Random
A double-precision floating point number greater than or equal to 0.0, and less than 1.0.
So, Eiffel feature names, and the names of .NET members made available to Eiffel for .NET programmers, are all lower case with words separated by underscores.
==Overloaded .NET Member Names==
The .NET object model allows overloading of function names. This means that a .NET type can support multiple functions with the same name, that vary only by the types of the arguments they accept. For example, the .NET type System. Text. StringBuilder supports nineteen overloaded versions of the Append function. Here are a couple of examples, in their .NET forms:
.NET function signature: Append(System.String)
Member of type System.Text.StringBuilder
Appends a copy of the specified string to the end of this instance.
.NET function signature: Append(System.Char)
Member of type System.Text.StringBuilder
Appends the string representation of a specified Unicode character to the end of this instance.
The Eiffel programming language does not allow overloading routine names. That means that you cannot code multiple routines with the same name in a single class. That in itself is not a problem. But it also means that to work in the .NET environment, where overloading is allowed some compromise has to be made. So, what happens is this: if you are programming in Eiffel for .NET and you are using types from a .NET assembly, those types will be presented to you as if they are Eiffel classes. We have already seen that the type and feature names will be shown in the Eiffel naming convention. With overloaded feature names, the presentation will use name augmentation to disambiguate the overloaded versions. What you see is a distinct feature name for each overloaded version. The basic feature name is augmented by adding the types of its respective arguments, separated by underscore.
Let's look again at the two Append
functions from System.Text.StringBuilder
.
.NET function signature: Append(System.String)
Known to Eiffel as: append_string (value: SYSTEM_STRING)
Member of type System.Text.StringBuilder, known to Eiffel as STRING_BUILDER
Appends a copy of the specified string to the end of this instance.
.NET function signature: Append(System.Char)
Known to Eiffel as: append_character (value: CHARACTER)
Member of type System.Text.StringBuilder, known to Eiffel as STRING_BUILDER
Appends the string representation of a specified Unicode character to the end of this instance.
The overloading story does not end quite yet. The .NET object model allows the overloading of constructors. This issue will be discussed in the section Constructors and Creation Procedures.
==.NET Properties as Eiffel Features==
Properties in .NET provide:
* the opportunity to '''strengthen encapsulation,''' because values cannot be receive assignment without executing the property's "set" code
* '''uniform access ''' queries because properties are queries, but unlike previous C-style OO languages in which properties did not exist, if a property is used in programming a client class, the programmer does not need to know whether the data provided by the property was done so from memory or through computation. This leaves the producer of the class with the property the latitude to change the implementation without breaking existing clients.
In Eiffel, the same goals are fulfilled, but a little differently. Simple attributes are well-encapsulated, because the Eiffel programming language does not allow direct assignment to them from outside the control of their class. So any assignment of the form x
. f
:= y
is not valid in Eiffel. To allow client to set values of the attribute f
, the producer of the class of which x
is an instance would have built a command (a "set_
" procedure) to do so. Then the code in a client to set f
would look like this: x
.set_f
(y
).
Uniform access is achieved in Eiffel through the way in which clientssee features which are queries. The code " print
( x
.count
)" applies the query count
to the object attached to x
and prints the result. You cannot tell by looking at this code whether count
is an attribute or a function, that is, whether the count
is returned from memory or through computation. In fact, it could be either, but that is a matter for its producer to deal with. As reuse consumers the implementation of count
is not important to us ...but the fact that the producer can change the implementation without causing our code to need modification is very important to us.
Because Eiffel does not support properties directly, the propertiesof typeswhich Eiffel for .NET programmers usefrom .NET assemblies have to be mapped to Eiffel features.
In order to ask for the property's current value (technically, receiving the result of the property's get
routine), a query feature is generated for the property. The query will be namedthe Eiffel name of the property.
As noted above, setting the value of a property cannot be done in Eiffel as it is done in C# and VB.NET because Eiffel disallows assignments of the form x
.f
:= y
. So, for each writable property, an Eiffel command feature is available to set the value of the property. The name for this command will be "set_
" followed by the Eiffel name for the property.
As a result, the code for using a .NET property looks very much like the code to use an Eiffel attribute. In the following code fragment, an instance of the type System.Windows.Forms.Form
which is available in Eiffel for .NET as WINFORMS_FORM
is used by an Eiffel client. System.Windows.Forms.Form
has a property Text
which is of type System.String
. Here the Text
property is being set using the set_text
feature, and then being recalled by using the query text
.
local
my_window: WINFORMS_FORM
my_string: SYSTEM_STRING
do
create my_window.make
my_window.set_text (my_window_title) -- Set Text property
my_string := my_window.text -- Query Text property
.
.
end
==Static Features in .NET==
In the .NET object model it is possible for certain members of a type to be "static". When these members are used, they are used without an instance of the class as a target. In essence, they are called on the class itself.
In Eiffel for .NET, these staticmembers will made available with feature names derivedusing the same conventions as ordinary features, but applying them will be a bit different.
There is not a concept analogous to static members in Eiffel. The model for object-oriented computation in Eiffel specifies that whenever feature application takes place, there must be an object, i.e. an instance of some class, that serves as a target.
In order to use .NET types that include static members, a special syntax has been added into Eiffel for .NET. The following example uses this syntax to call a static function:
local
my_window: WINFORMS_FORM
do
create my_window.make
my_window.set_text (my_window_title)
.
.
{WINFORMS_APPLICATION}.run_form (my_window)
end
The type System.Windows.Forms.Application
is used here. It is available to Eiffel under the name WINFORMS_APPLICATION
. The static member being used is Run
, in particular the overloaded version of Run
which takes an argument of type System.Windows.Forms.Form
. That version is available in Eiffel under the name run_form
.
The important thing to see here is that when you need to apply a static member, you introduce the call with the keyword feature
. Then enclose the type name in braces and apply the feature as if it were targeted to an object. This isfairly close to the way that the call would be made in C#, where the feature name would be applied to the type name, versus a target object:
{
Form my_window;
my_window = new Form();
my_window.Text = "Hello World!";
.
.
Application.Run(my_window); // This is C#
}