The material in this book is designed to help you apply the EiffelStudio interactive development environment to your software development challenges.
EiffelStudio is specifically crafted to make it easier for developers to create high quality software systems using the Eiffel method and language. EiffelStudio is continually improving, with new features and capabilities added in every new release.
For detailed installation instructions please follow the link for the product your are installing.
Select the operating system you are using for detailed installation instructions:
Note: The Mac OS X version is currently only available under the GPL license and can be downloaded by following the instructions at http://dev.eiffel.com/EiffelOnMac. The instructions below are not currently applicable for Mac OS X.
Contents
|
| Computer/Processor | x86-64 |
| Operating System | Mac OS X 10.8 or above |
| C compiler | gcc included in XCode |
| Memory | 512MB of RAM (1GB recommended) |
| Hard Disk | 400MB of hard disk space (1GB recommended) |
| Drive | CD-ROM or DVD drive (not required when downloading EiffelStudio) |
| Display | 1024 x 768 or higher resolution video adapter and monitor |
| Peripherals | Keyboard and mouse or compatible pointing device |
| ISE_PLATFORM | macosx-x86' for x86 based CPU and macosx-x86-64 for x64 based CPU. |
After downloading the EiffelXX.dmg installation package (where XX stands for the EiffelStudio version), double click on it to mount the disk image. Then double click on the EiffelXX.pkg file to launch the installation procedure. Follow the steps indicated in the dialogs to complete the installation.
Insert the CD into your CD-ROM drive. Open the CD-ROM contents and double click on the EiffelXX.pkg file to launch the installation procedure. Follow the steps indicated in the dialogs to complete the installation.
Run EiffelStudio, located at /Developers/Applications/EiffelXX/EiffelStudio. Enter the information located inside the box that contains your copy of the EiffelStudio Enterprise Edition. Once the information is correct, the Register button will be enabled. Click Register to actually register EiffelStudio.
You now need to launch EiffelStudio to register your copy. Follow the instructions located in the Starting EiffelStudio section below. The first time you launch EiffelStudio, you will be asked for an activation key through the following dialog:
By clicking on the http://activate.eiffel.com URL, a new web browser will appear with the requested fields automatically filled in with the appropriate information. Simply click Activate and a new page with an activation code will appear. Copy and paste the activation code in the first field and the Activate button should be enabled to let you activate your copy.
You can activate your copy up to three times. Once you have reached this threshold and need to reinstall your copy, contact Eiffel Software to request one more activation.
If no web broswer appears, it is most likely because Safari is not installed on your machine or is not in your path. Instead you should manually launch a new web browser and go to the page http://activate.eiffel.com and enter the information manually. Then follow the above instructions as if the browser had been properly launched.
You may receive the following dialog when launching EiffelStudio:
This probably means that the register program was not launched or did not succeed in storing data to the following file /Developer/Applications/EiffelXX/EiffelStudio.app/Contents/Resources/EiffelXX/install/limand/.ec_license. To solve this, rerun the register program with a user account that has permissions to write at /Developer/Applications/EiffelXX/EiffelStudio.app/Contents/Resources/EiffelXX/install/limand and enter your Username and CD Key.
Now everything should be properly installed and you should be able to run the compiler. You can now launch EiffelStudio from the Finder under /Developer/Applications/EiffelXX/. If you are a new user to EiffelStudio, we recommend that you follow the guided tour .
Contents
|
| Computer/Processor | PC with 300 MHz or higher Pentium II class processor or equivalent recommended. |
| Operating System | FreeBSD 5.2 with either Gnome 2.6 or GTK+ 2.4. |
| C compiler | gcc |
| Memory | 512 MB of RAM (1GB recommended). |
| Hard Disk | 400Mb uncompressed hard disk space (700Mb recommended). |
| Drive | CD-ROM or DVD drive (not required when downloading EiffelStudio). |
| Display | 1024 x 768 or higher resolution video adapter and monitor. |
| Peripherals | Keyboard and mouse or compatible pointing device. |
| ISE_PLATFORM | freebsd-x86 for x86 based CPU and freebsd-x86-64 for x64 based CPU. |
EiffelStudio requires GTK+ 2.4.0 or above to function properly. You can check that you have this installed correctly by typing the following command:
pkg-config --modversion gtk+-2.0
The command should succeed and the version number of GTK+ should appear. If it is not 2.4.0 or above then you cannot continue the installation of EiffelStudio. You first need to install GTK+ 2.4.0.
After downloading the installation package, you should manually extract its contents to your hard drive. For example, you can extract it into /usr/local using the following commands (assuming that you have permission to /usr/local and that the installation package was saved in /tmp/EiffelXX.tar.bz2, where XX corresponds to the EiffelStudio version number):
cd /usr/local tar xvfj /tmp/EiffelXX.tar.bz2
This will install EiffelStudio files into /usr/local/EiffelXX. Once this is done, jump to the Setting up EiffelStudio section in order to complete the installation of EiffelStudio.
Insert the CD into your CD-ROM drive. You should manually extract its contents to your hard drive. For example you can extract it in /usr/local using the following commands (assuming that you have permission to /usr/local and that the CD is mounted on /mnt/cdrom):
cd /usr/local cp -r /mnt/cdrom/EiffelXX .
This will install the EiffelStudio files into /usr/local/EiffelXX. To complete the installation of EiffelStudio, jump to the next section, Setting up EiffelStudio.
Once the files have been installed, you should define the following environment variables in order to run EiffelStudio:
and add $ISE_EIFFEL/studio/spec/$ISE_PLATFORM/bin to your PATH environment variable.
Using sh or bash as a shell, it suffices to type the following commands:
export ISE_EIFFEL=/usr/local/EiffelXX export ISE_PLATFORM=freebsd-x86 export PATH=$PATH:$ISE_EIFFEL/studio/spec/$ISE_PLATFORM/bin
Using csh or tcsh as a shell, it suffices to type the following commands:
setenv ISE_EIFFEL /usr/local/EiffelXX setenv ISE_PLATFORM freebsd-x86 set path = ($path $ISE_EIFFEL/studio/spec/$ISE_PLATFORM/bin)
If you are using the Enterprise edition, please follow the instructions of the next section, Registering the Enterprise Edition, otherwise jump to the Using EiffelStudio section at the end of this document.
This step assumes you have followed the instructions in the Setting up EiffelStudio section. Perform the following commands to start the registration process:
cd $ISE_EIFFEL
./registerA dialog asking for your Username and CD Key should appear as it does below:
Enter the information located inside the box that contains your copy of the EiffelStudio Enterprise Edition. Once the information is correct, the Register button will be enabled. Click Register to actually register EiffelStudio.
The first time you launch EiffelStudio, you will be asked for an activation key through the following dialog:
By clicking on the http://activate.eiffel.com URL, a new web browser will appear with the requested fields automatically filled in with the appropriate information. Simply click Activate and a new page with an activation code will appear. Copy and paste the activation code in the first field and the Activate button should be enabled to let you activate your copy.
You can activate your copy up to three times. Once you have reached this threshold and need to reinstall your copy, contact Eiffel Software to request one more activation.
If no web browser appears, it is most likely because firefox is not installed on your machine or is not in your path. Instead you should manually launch a new web browser, go to the page http://activate.eiffel.com , and enter the information manually. Then follow the above instructions as if the browser had been properly launched.
You may receive the following dialog when launching EiffelStudio:
This probably means that the register program was not launched or did not succeed in storing data to the following file $ISE_EIFFEL/install/limand/.ec_license. To solve this, rerun the register program with a user account that has permissions to write at $ISE_EIFFEL/install/limand and enter your Username and CD Key.
Once this is done, you can jump to the next section, Using EiffelStudio.
Now everything should be properly installed and you should be able to run the compiler. Launch estudio for the interactive graphical user interface of the compiler, or launch ec for the command line interface. If you are a new user to EiffelStudio, we recommend that you follow the guided tour.
EiffelStudio for Unix uses the GTK+ theme engine to allow for custom appearance such as changing the default font size and color of windows, etc. If you do not have a theme manager (such as that provided with Gnome) you can copy the .gtkrc-2.0 file from $ISE_EIFFEL/eifinit/studio/spec/gtk directory to your $HOME directory.
Contents
|
| Computer/Processor | AlphaServer. |
| Operating System | HP OpenVMS/Alpha version 7.3.2 with DECWindows and GTK+ 1.2.10. |
| C compiler | Compaq C compiler V6 or later. |
| Memory | 512MB of RAM (1GB recommended). |
| Hard Disk | 1GB free disk space on an ODS-5 formatted volume, plus an additional 1GB of free space while performing the software installation. |
| Drive | CD-ROM or DVD drive (not required when downloading EiffelStudio). |
| Display | 1024 x 768 or higher resolution video adapter and monitor. |
| Peripherals | Keyboard and mouse or compatible pointing device. |
EiffelStudio requires GTK+ 1.2.10 or above to function properly. You can check that you have this installed correctly by typing the following command:
gtk-config --version
The command should succeed and the version number of GTK+ should appear. If it is not 1.2.10 or above then you cannot continue the installation of EiffelStudio. You first need to install GTK+ 1.2.10.
After downloading the eifXXvms.zip installation package (where XX stands for the EiffelStudio version number), unzip the distribution into temp:[dir] where where temp:[dir] is the location of a temporary directory:
unzip eifXXvms.zip temp:[dir]
And use the following commands to install the files into eiffel_installation_path where eiffel_installation_path is a device:[directory] on an ODS-5 volume:
set file/attrib=(org:seq,rfm:fix,lrl:9216) temp:[dir]eifXXvms.save backup temp:[dir]eifXXvms.save/save eiffel_installation_path
You must mount the installation CD-ROM volume with the following qualifier:
mount cd_dev:/media_format=cdrom/undefined_fat=fixed:cr:9216
where cd_dev: is the CD-ROM device. And use the following commands to install the files into eiffel_installation_path where eiffel_installation_path is a device:[directory] on an ODS-5 volume:
backup cd_dev:[000000]eifXXvms.save/save eiffel_installation_path
You must define a system-wide rooted logical name to reference the installation directory, for instance:
define/system EIFFELXX eiffel_installation_path:[directory.] /trans=conceal
To use EiffelStudio for OpenVMS, run the setup procedure to define the environment:
@eiffel_installation_path:[000000]setup
This will define the logical names and DCL symbols required to run Eiffel.
Once the files are copied and once the environment is setup up set, you need to register EiffelStudio. To do so type the following command:
RUN ISE_EIFFEL:[000000]register
A dialog asking for your Username and CD Key should appear as it does below:
Enter the information located inside the box that contains your copy of the EiffelStudio Enterprise Edition. Once the information is correct, the Register button will be enabled. Click Register to actually register EiffelStudio.
The first time you launch EiffelStudio, you will be asked for an activation key through the following dialog:
By clicking on the http://activate.eiffel.com URL, a new web browser will appear with the requested fields automatically filled in with the appropriate information. Simply click Activate and a new page with an activation code will appear. Copy and paste the activation code in the first field and the Activate button should be enabled to let you activate your copy.
You can activate your copy up to three times. Once you have reached this threshold and need to reinstall your copy, contact Eiffel Software to request one more activation.
If no web broswer appears, it is most likely because netscape is not installed on your machine or is not in your path. Instead you should manually launch a new web browser and go to the page http://activate.eiffel.com and enter the information manually. Then follow the above instructions as if the browser had been properly launched.
You may receive the following dialog when launching EiffelStudio:
This probably means that the register program was not launched or did not succeed in storing data to the following file ISE_EIFFEL:[install.limand].ec_license. To solve this, rerun the register program with a user account that has permissions to write at ISE_EIFFEL:[install.limand] and enter your Username and CD Key.
Once this is done you can jump to the next section "Using EiffelStudio."
Contents
|
| Computer/Processor | HP-PA. |
| Operating System | HP-UX 11 with GTK+ 2.4. |
| C compiler | HP C compiler |
| Memory | 512MB of RAM (1GB recommended). |
| Hard Disk | 500MB of hard disk space (1GB recommended). |
| Drive | CD-ROM or DVD drive (not required when downloading EiffelStudio). |
| Display | 1024 x 768 or higher resolution video adapter and monitor. |
| Peripherals | Keyboard and mouse or compatible pointing device. |
| ISE_PLATFORM | hpux-11. |
EiffelStudio requires GTK+ 2.4.0 or above to function properly. You can check that you have this installed correctly by typing the following command:
pkg-config --modversion gtk+-2.0
The command should succeed and the version number of GTK+ should appear. If it is not 2.4.0 or above then you cannot continue the installation of EiffelStudio. You first need to install GTK+ 2.4.0.
After downloading the installation package, you should manually extract its contents to your hard drive. For example, you can extract it into /usr/local using the following commands (assuming that you have permission to /usr/local and that the installation package was saved in /tmp/EiffelXX.tar.bz2, where XX stands for the EiffelStudio version number):
cd /usr/local tar xvfj /tmp/EiffelXX.tar.bz2
This will install EiffelStudio files into /usr/local/EiffelXX. Once this is done, jump to the Setting up EiffelStudio section in order to complete the installation of EiffelStudio.
Insert the CD into your CD-ROM drive. You should manually extract its contents to your hard drive. For example you can extract it in /usr/local using the following commands (assuming that you have permission to /usr/local and that the CD is mounted on /mnt/cdrom):
cd /usr/local cp -r /mnt/cdrom/EiffelXX .
This will install the EiffelStudio files into /usr/local/EiffelXX. To complete the installation of EiffelStudio, jump to the next section, Setting up EiffelStudio.
Once the files have been installed, you should define the following environment variables in order to run EiffelStudio:
and add $ISE_EIFFEL/studio/spec/$ISE_PLATFORM/bin to your PATH environment variable.
Using sh or bash as a shell, it suffices to type the following commands:
export ISE_EIFFEL=/usr/local/EiffelXX export ISE_PLATFORM=hpux-11 export PATH=$PATH:$ISE_EIFFEL/studio/spec/$ISE_PLATFORM/bin
Using csh or tcsh as a shell, it suffices to type the following commands:
setenv ISE_EIFFEL /usr/local/EiffelXX setenv ISE_PLATFORM hpux-11 set path = ($path $ISE_EIFFEL/studio/spec/$ISE_PLATFORM/bin)
If you are using the Enterprise edition, please follow the instructions of the next section, Registering the Enterprise Edition , otherwise jump to the Using EiffelStudio section at the end of this document.
This step assumes you have followed the instructions in the Setting up EiffelStudio section. Perform the following commands to start the registration process:
cd $ISE_EIFFEL
./registerA dialog asking for your Username and CD Key should appear as it does below:
Enter the information located inside the box that contains your copy of the EiffelStudio Enterprise Edition. Once the information is correct, the Register button will be enabled. Click Register to actually register EiffelStudio.
The first time you launch EiffelStudio, you will be asked for an activation key through the following dialog:
By clicking on the http://activate.eiffel.com URL, a new web browser will appear with the requested fields automatically filled in with the appropriate information. Simply click Activate and a new page with an activation code will appear. Copy and paste the activation code in the first field and the Activate button should be enabled to let you activate your copy.
You can activate your copy up to three times. Once you have reached this threshold and need to reinstall your copy, contact Eiffel Software to request one more activation.
If no web browser appears, it is most likely because firefox is not installed on your machine or is not in your path. Instead you should manually launch a new web browser, go to the page http://activate.eiffel.com , and enter the information manually. Then follow the above instructions as if the browser had been properly launched.
You may receive the following dialog when launching EiffelStudio:
This probably means that the register program was not launched or did not succeed in storing data to the following file $ISE_EIFFEL/install/limand/.ec_license. To solve this, rerun the register program with a user account that has permissions to write at $ISE_EIFFEL/install/limand and enter your Username and CD Key.
Once this is done, you can jump to the next section, Using EiffelStudio .
Now everything should be properly installed and you should be able to run the compiler. Launch estudio for the interactive graphical user interface of the compiler, or launch ec for the command line interface. If you are a new user to EiffelStudio, we recommend that you follow the guided tour.
EiffelStudio for Unix uses the GTK+ theme engine to allow for custom appearance such as changing the default font size and color of windows, etc. If you do not have a theme manager (such as that provided with Gnome) you can copy the .gtkrc-2.0 file from $ISE_EIFFEL/eifinit/studio/spec/gtk directory to your $HOME directory.
Contents
|
| Computer/Processor | AlphaServer. |
| Operating System | HP Tru64 UNIX 5.1B with GTK+ 2.4. |
| C compiler | HP C compiler |
| Memory | 512MB of RAM (1GB recommended). |
| Hard Disk | 500MB of hard disk space (1GB recommended). |
| Drive | CD-ROM or DVD drive (not required when downloading EiffelStudio). |
| Display | 1024 x 768 or higher resolution video adapter and monitor. |
| Peripherals | Keyboard and mouse or compatible pointing device. |
| ISE_PLATFORM | alpha. |
EiffelStudio requires GTK+ 2.4.0 or above to function properly. You can check that you have this installed correctly by typing the following command:
pkg-config --modversion gtk+-2.0
The command should succeed and the version number of GTK+ should appear. If it is not 2.4.0 or above then you cannot continue the installation of EiffelStudio. You first need to install GTK+ 2.4.0.
After downloading the installation package, you should manually extract its contents to your hard drive. For example, you can extract it into /usr/local using the following commands (assuming that you have permission to /usr/local and that the installation package was saved in /tmp/EiffelXX.tar.bz2, where XX stands for the EiffelStudio version):
cd /usr/local tar xvfj /tmp/EiffelXX.tar.bz2
This will install EiffelStudio files into /usr/local/EiffelXX. Once this is done, jump to the Setting up EiffelStudio section in order to complete the installation of EiffelStudio.
Insert the CD into your CD-ROM drive. You should manually extract its contents to your hard drive. For example you can extract it in /usr/local using the following commands (assuming that you have permission to /usr/local and that the CD is mounted on /mnt/cdrom):
cd /usr/local cp -r /mnt/cdrom/EiffelXX .
This will install the EiffelStudio files into /usr/local/EiffelXX. To complete the installation of EiffelStudio, jump to the next section, Setting up EiffelStudio.
Once the files have been installed, you should define the following environment variables in order to run EiffelStudio:
and add $ISE_EIFFEL/studio/spec/$ISE_PLATFORM/bin to your PATH environment variable.
Using sh or bash as a shell, it suffices to type the following commands:
export ISE_EIFFEL=/usr/local/EiffelXX export ISE_PLATFORM=alpha export PATH=$PATH:$ISE_EIFFEL/studio/spec/$ISE_PLATFORM/bin
Using csh or tcsh as a shell, it suffices to type the following commands:
setenv ISE_EIFFEL /usr/local/EiffelXX setenv ISE_PLATFORM alpha set path = ($path $ISE_EIFFEL/studio/spec/$ISE_PLATFORM/bin)
If you are using the Enterprise edition, please follow the instructions of the next section, Registering the Enterprise Edition, otherwise jump to the Using EiffelStudio section at the end of this document.
This step assumes you have followed the instructions in the Setting up EiffelStudio section. Perform the following commands to start the registration process:
cd $ISE_EIFFEL
./registerA dialog asking for your Username and CD Key should appear as it does below:
Enter the information located inside the box that contains your copy of the EiffelStudio Enterprise Edition. Once the information is correct, the Register button will be enabled. Click Register to actually register EiffelStudio.
The first time you launch EiffelStudio, you will be asked for an activation key through the following dialog:
By clicking on the http://activate.eiffel.com URL, a new web browser will appear with the requested fields automatically filled in with the appropriate information. Simply click Activate and a new page with an activation code will appear. Copy and paste the activation code in the first field and the Activate button should be enabled to let you activate your copy.
You can activate your copy up to three times. Once you have reached this threshold and need to reinstall your copy, contact Eiffel Software to request one more activation.
If no web browser appears, it is most likely because firefox is not installed on your machine or is not in your path. Instead you should manually launch a new web browser, go to the page http://activate.eiffel.com , and enter the information manually. Then follow the above instructions as if the browser had been properly launched.
You may receive the following dialog when launching EiffelStudio:
This probably means that the register program was not launched or did not succeed in storing data to the following file $ISE_EIFFEL/install/limand/.ec_license. To solve this, rerun the register program with a user account that has permissions to write at $ISE_EIFFEL/install/limand and enter your Username and CD Key.
Once this is done, you can jump to the next section, Using EiffelStudio.
Now everything should be properly installed and you should be able to run the compiler. Launch estudio for the interactive graphical user interface of the compiler, or launch ec for the command line interface. If you are a new user to EiffelStudio, we recommend that you follow the guided tour.
EiffelStudio for Unix uses the GTK+ theme engine to allow for custom appearance such as changing the default font size and color of windows, etc. If you do not have a theme manager (such as that provided with Gnome) you can copy the .gtkrc-2.0 file from $ISE_EIFFEL/eifinit/studio/spec/gtk directory to your $HOME directory.
Contents
|
| Computer/Processor | PC with 300 MHz or higher Pentium II class processor or equivalent recommended. |
| Operating System | Fedora Core 2, Slackware 10 or any Linux system with glibc 2.3 and either Gnome 2.6 or GTK+ 2.4. |
| C compiler | gcc |
| Memory | 512MB of RAM (1GB recommended). |
| Hard Disk | 500MB of hard disk space (1GB recommended). |
| Drive | CD-ROM or DVD drive (not required when downloading EiffelStudio). |
| Display | 1024 x 768 or higher resolution video adapter and monitor. |
| Peripherals | Keyboard and mouse or compatible pointing device. |
| ISE_PLATFORM | linux-x86 for x86 based CPU, linux-x86-64 for x64 based CPU. |
EiffelStudio requires GTK+ 2.4.0 or above to function properly. You can check that you have this installed correctly by typing the following command:
pkg-config --modversion gtk+-2.0
The command should succeed and the version number of GTK+ should appear. If it is not 2.4.0 or above then you cannot continue the installation of EiffelStudio. You first need to install GTK+ 2.4.0.
On some Linux distribution the Xtst library is required but not installed by default. You have to make sure it is installed by using the instruction of your Linux distribution.
For example, on Debian based distribution you need to do:
sudo apt-get install libgtk2.0-dev sudo apt-get install libxtst-dev
After downloading the installation package, you should manually extract its contents to your hard drive. For example, you can extract it into /usr/local using the following commands (assuming that you have permission to /usr/local and that the installation package was saved in /tmp/EiffelXX.tar.bz2, where XX stands for the EiffelStudio version):
cd /usr/local tar xvfj /tmp/EiffelXX.tar.bz2
This will install EiffelStudio files into /usr/local/EiffelXX. Once this is done, jump to the Setting up EiffelStudio section in order to complete the installation of EiffelStudio.
Insert the CD into your CD-ROM drive. You should manually extract its contents to your hard drive. For example you can extract it in /usr/local using the following commands (assuming that you have permission to /usr/local and that the CD is mounted on /mnt/cdrom):
cd /usr/local cp -r /mnt/cdrom/EiffelXX .
This will install the EiffelStudio files into /usr/local/EiffelXX. To complete the installation of EiffelStudio, jump to the next section, Setting up EiffelStudio.
Once the files have been installed, you should define the following environment variables in order to run EiffelStudio:
and add $ISE_EIFFEL/studio/spec/$ISE_PLATFORM/bin to your PATH environment variable.
Using sh or bash as a shell, it suffices to type the following commands:
export ISE_EIFFEL=/usr/local/EiffelXX export ISE_PLATFORM=linux-x86 export PATH=$PATH:$ISE_EIFFEL/studio/spec/$ISE_PLATFORM/bin
Using csh or tcsh as a shell, it suffices to type the following commands:
setenv ISE_EIFFEL /usr/local/EiffelXX setenv ISE_PLATFORM linux-x86 set path = ($path $ISE_EIFFEL/studio/spec/$ISE_PLATFORM/bin)
If you are using the Enterprise edition, please follow the instructions of the next section, Registering the Enterprise Edition, otherwise jump to the Using EiffelStudio section at the end of this document.
This step assumes you have followed the instructions in the Setting up EiffelStudio section. Perform the following commands to start the registration process:
cd $ISE_EIFFEL
./registerA dialog asking for your Username and CD Key should appear as it does below:
Enter the information located inside the box that contains your copy of the EiffelStudio Enterprise Edition. Once the information is correct, the Register button will be enabled. Click Register to actually register EiffelStudio.
The first time you launch EiffelStudio, you will be asked for an activation key through the following dialog:
By clicking on the http://activate.eiffel.com URL, a new web browser will appear with the requested fields automatically filled in with the appropriate information. Simply click Activate and a new page with an activation code will appear. Copy and paste the activation code in the first field and the Activate button should be enabled to let you activate your copy.
You can activate your copy up to three times. Once you have reached this threshold and need to reinstall your copy, contact Eiffel Software to request one more activation.
If no web browser appears, it is most likely because firefox is not installed on your machine or is not in your path. Instead you should manually launch a new web browser, go to the page http://activate.eiffel.com , and enter the information manually. Then follow the above instructions as if the browser had been properly launched.
You may receive the following dialog when launching EiffelStudio:
This probably means that the register program was not launched or did not succeed in storing data to the following file $ISE_EIFFEL/install/limand/.ec_license. To solve this, rerun the register program with a user account that has permissions to write at $ISE_EIFFEL/install/limand and enter your Username and CD Key.
Once this is done, you can jump to the next section, Using EiffelStudio .
Now everything should be properly installed and you should be able to run the compiler. Launch estudio for the interactive graphical user interface of the compiler, or launch ec for the command line interface. If you are a new user to EiffelStudio, we recommend that you follow the guided tour.
EiffelStudio for Unix uses the GTK+ theme engine to allow for custom appearance such as changing the default font size and color of windows, etc. If you do not have a theme manager (such as that provided with Gnome) you can copy the .gtkrc-2.0 file from $ISE_EIFFEL/eifinit/studio/spec/gtk directory to your $HOME directory.
Contents
|
| Computer/Processor | PowerPC. |
| Operating System | Yellow Dog Linux 4.0 with either Gnome 2.6 or GTK+ 2.4. |
| C compiler | gcc |
| Memory | 512MB of RAM (1GB recommended). |
| Hard Disk | 500MB of hard disk space (1GB recommended). |
| Drive | CD-ROM or DVD drive (not required when downloading EiffelStudio). |
| Display | 1024 x 768 or higher resolution video adapter and monitor. |
| Peripherals | Keyboard and mouse or compatible pointing device. |
| ISE_PLATFORM | linux-ppc. |
EiffelStudio requires GTK+ 2.4.0 or above to function properly. You can check that you have this installed correctly by typing the following command:
pkg-config --modversion gtk+-2.0
The command should succeed and the version number of GTK+ should appear. If it is not 2.4.0 or above then you cannot continue the installation of EiffelStudio. You first need to install GTK+ 2.4.0.
After downloading the installation package, you should manually extract its contents to your hard drive. For example, you can extract it into /usr/local using the following commands (assuming that you have permission to /usr/local and that the installation package was saved in /tmp/EiffelXX.tar.bz2, where XX stands for the EiffelStudio version):
cd /usr/local tar xvfj /tmp/EiffelXX.tar.bz2
This will install EiffelStudio files into /usr/local/EiffelXX. Once this is done, jump to the Setting up EiffelStudio section in order to complete the installation of EiffelStudio.
Insert the CD into your CD-ROM drive. You should manually extract its contents to your hard drive. For example you can extract it in /usr/local using the following commands (assuming that you have permission to /usr/local and that the CD is mounted on /mnt/cdrom):
cd /usr/local cp -r /mnt/cdrom/EiffelXX .
This will install the EiffelStudio files into /usr/local/EiffelXX. To complete the installation of EiffelStudio, jump to the next section, Setting up EiffelStudio.
Once the files have been installed, you should define the following environment variables in order to run EiffelStudio:
and add $ISE_EIFFEL/studio/spec/$ISE_PLATFORM/bin to your PATH environment variable.
Using sh or bash as a shell, it suffices to type the following commands:
export ISE_EIFFEL=/usr/local/EiffelXX export ISE_PLATFORM=linux-ppc export PATH=$PATH:$ISE_EIFFEL/studio/spec/$ISE_PLATFORM/bin
Using csh or tcsh as a shell, it suffices to type the following commands:
setenv ISE_EIFFEL /usr/local/EiffelXX setenv ISE_PLATFORM linux-ppc set path = ($path $ISE_EIFFEL/studio/spec/$ISE_PLATFORM/bin)
If you are using the Enterprise edition, please follow the instructions of the next section, Registering the Enterprise Edition, otherwise jump to the Using EiffelStudio section at the end of this document.
This step assumes you have followed the instructions in the [[#Setting up EiffelStudio|Setting up EiffelStudio] section. Perform the following commands to start the registration process:
cd $ISE_EIFFEL
./registerA dialog asking for your Username and CD Key should appear as it does below:
Enter the information located inside the box that contains your copy of the EiffelStudio Enterprise Edition. Once the information is correct, the Register button will be enabled. Click Register to actually register EiffelStudio.
The first time you launch EiffelStudio, you will be asked for an activation key through the following dialog:
By clicking on the http://activate.eiffel.com URL, a new web browser will appear with the requested fields automatically filled in with the appropriate information. Simply click Activate and a new page with an activation code will appear. Copy and paste the activation code in the first field and the Activate button should be enabled to let you activate your copy.
You can activate your copy up to three times. Once you have reached this threshold and need to reinstall your copy, contact Eiffel Software to request one more activation.
If no web browser appears, it is most likely because firefox is not installed on your machine or is not in your path. Instead you should manually launch a new web browser, go to the page http://activate.eiffel.com , and enter the information manually. Then follow the above instructions as if the browser had been properly launched.
You may receive the following dialog when launching EiffelStudio:
This probably means that the register program was not launched or did not succeed in storing data to the following file $ISE_EIFFEL/install/limand/.ec_license. To solve this, rerun the register program with a user account that has permissions to write at $ISE_EIFFEL/install/limand and enter your Username and CD Key.
Once this is done, you can jump to the next section, Using EiffelStudio.
Now everything should be properly installed and you should be able to run the compiler. Launch estudio for the interactive graphical user interface of the compiler, or launch ec for the command line interface. If you are a new user to EiffelStudio, we recommend that you follow the guided tour.
EiffelStudio for Unix uses the GTK+ theme engine to allow for custom appearance such as changing the default font size and color of windows, etc. If you do not have a theme manager (such as that provided with Gnome) you can copy the .gtkrc-2.0 file from $ISE_EIFFEL/eifinit/studio/spec/gtk directory to your $HOME directory.
Contents
|
| Computer/Processor | PC with 1GHz or higher Intel/AMD processor or equivalent recommended. |
| Operating System | Windows 2000/XP/2003/Vista/Win7. |
| C compiler | Microsoft Visual Studio 2005 or greater, or using MinGW (gcc) included in the EiffelStudio delivery |
| Memory | 512MB of RAM (1GB recommended). |
| Hard Disk | 500MB of hard disk space (1GB recommended). Hard disk space requirements will vary depending on configuration; custom installation choices may require more or less space. Space required for installation of the Microsoft .NET Framework will also be required. |
| Drive | CD-ROM drive (not required when downloading EiffelStudio). |
| Display | 1024 x 768 or higher resolution video adapter and monitor. |
| Peripherals | Keyboard and mouse or compatible pointing device. |
| ISE_PLATFORM | windows for 32 bits version of Windows, win64 for 64 bits version of Windows. |
After downloading the EiffelXX.msi installation package, right click on it and select Install. This will launch the installation procedure. Follow the steps indicated in the dialogs to complete the installation.
Insert the CD into your CD-ROM drive. If you have the autorun facility enabled, the installation process will automatically be launched. Otherwise you can launch it by executing EiffelXX.msi located at the root of the CD. During the installation you will be asked for your Username and CD Key
Enter the information located inside the box that contains your copy of the EiffelStudio Enterprise Edition, or that you will have received via email. Once the information is correct, the Next button will be enabled. Click Next and follow the steps indicated in the dialogs to complete the installation.
Once installed, the first time you launch EiffelStudio, you will be asked for an activation key through the following dialog:
By clicking on the http://activate.eiffel.com URL, a new web browser will appear with the requested fields automatically filled in with the appropriate information. Simply click Activate and a new page with an activation code will appear. Copy and paste the activation code in the first field and the Activate button should be enabled to let you activate your copy.
You can activate your copy up to three times. Once you have reached this threshold and need to reinstall your copy, contact Eiffel Software to request one more activation.
You may receive the following dialog when launching EiffelStudio:
This probably means that EiffelStudio was not properly installed using the setup.exe program. Uninstall EiffelStudio and rerun the installation procedure by making sure to launch setup.exe and enter your Username and CD Key.
To enable .NET support in EiffelStudio, it is necessary to install the Microsoft .NET Framework prior to starting the installation of EiffelStudio. EiffelStudio currently supports all the versions of the .NET Framework up to 4.0.
EiffelStudio will not run on Windows 95, 98 and Me. Contact Eiffel Software directly if you need support for those OSes. EiffelStudio generated code could run on 95, 98 and Me if no UI is being used. If the UI is used it could run but it requires installing the Microsoft Layer for Unicode.
Now everything should be properly installed and you should be able to run the compiler. You can now launch EiffelStudio from the Start menu or from the EiffelStudio shortcut on your desktop. If you are a new user to EiffelStudio, we recommend that you follow the guided tour .
Contents
|
| Computer/Processor | MIPS. |
| Operating System | Irix 6.5 with either Gnome 2.6 or GTK+ 2.4. |
| C compiler | MIPSPro C compiler V2.4 or later. |
| Memory | 512MB of RAM (1GB recommended). |
| Hard Disk | 500MB of hard disk space (1GB recommended). |
| Drive | CD-ROM or DVD drive (not required when downloading EiffelStudio). |
| Display | 1024 x 768 or higher resolution video adapter and monitor. |
| Peripherals | Keyboard and mouse or compatible pointing device. |
| ISE_PLATFORM | irix-mips for 32 bits, irix-mips-64 for 64 bits. |
EiffelStudio requires GTK+ 2.4.0 or above to function properly. You can check that you have this installed correctly by typing the following command:
pkg-config --modversion gtk+-2.0
The command should succeed and the version number of GTK+ should appear. If it is not 2.4.0 or above then you cannot continue the installation of EiffelStudio. You first need to install GTK+ 2.4.0.
After downloading the installation package, you should manually extract its contents to your hard drive. For example, you can extract it into /usr/local using the following commands (assuming that you have permission to /usr/local and that the installation package was saved in /tmp/EiffelXX.tar.bz2, where XX stands for the EiffelStudio version):
cd /usr/local tar xvfj /tmp/EiffelXX.tar.bz2
This will install EiffelStudio files into /usr/local/EiffelXX. Once this is done, jump to the Setting up EiffelStudio section in order to complete the installation of EiffelStudio.
Insert the CD into your CD-ROM drive. You should manually extract its contents to your hard drive. For example you can extract it in /usr/local using the following commands (assuming that you have permission to /usr/local and that the CD is mounted on /mnt/cdrom):
cd /usr/local cp -r /mnt/cdrom/EiffelXX .
This will install the EiffelStudio files into /usr/local/EiffelXX. To complete the installation of EiffelStudio, jump to the next section, Setting up EiffelStudio.
Once the files have been installed, you should define the following environment variables in order to run EiffelStudio:
and add $ISE_EIFFEL/studio/spec/$ISE_PLATFORM/bin to your PATH environment variable.
Using sh or bash as a shell, it suffices to type the following commands:
export ISE_EIFFEL=/usr/local/EiffelXX export ISE_PLATFORM=irix-mips export PATH=$PATH:$ISE_EIFFEL/studio/spec/$ISE_PLATFORM/bin
Using csh or tcsh as a shell, it suffices to type the following commands:
setenv ISE_EIFFEL /usr/local/EiffelXX setenv ISE_PLATFORM irix-mips set path = ($path $ISE_EIFFEL/studio/spec/$ISE_PLATFORM/bin)
If you are using the Enterprise edition, please follow the instructions of the next section, Registering the Enterprise Edition, otherwise jump to the Using EiffelStudio section at the end of this document.
This step assumes you have followed the instructions in the Setting up EiffelStudio section. Perform the following commands to start the registration process:
cd $ISE_EIFFEL
./registerA dialog asking for your Username and CD Key should appear as it does below:
Enter the information located inside the box that contains your copy of the EiffelStudio Enterprise Edition. Once the information is correct, the Register button will be enabled. Click Register to actually register EiffelStudio.
The first time you launch EiffelStudio, you will be asked for an activation key through the following dialog:
By clicking on the http://activate.eiffel.com URL, a new web browser will appear with the requested fields automatically filled in with the appropriate information. Simply click Activate and a new page with an activation code will appear. Copy and paste the activation code in the first field and the Activate button should be enabled to let you activate your copy.
You can activate your copy up to three times. Once you have reached this threshold and need to reinstall your copy, contact Eiffel Software to request one more activation.
If no web browser appears, it is most likely because firefox is not installed on your machine or is not in your path. Instead you should manually launch a new web browser, go to the page http://activate.eiffel.com , and enter the information manually. Then follow the above instructions as if the browser had been properly launched.
You may receive the following dialog when launching EiffelStudio:
This probably means that the register program was not launched or did not succeed in storing data to the following file $ISE_EIFFEL/install/limand/.ec_license. To solve this, rerun the register program with a user account that has permissions to write at $ISE_EIFFEL/install/limand and enter your Username and CD Key.
Once this is done, you can jump to the next section, Using EiffelStudio.
Now everything should be properly installed and you should be able to run the compiler. Launch estudio for the interactive graphical user interface of the compiler, or launch ec for the command line interface. If you are a new user to EiffelStudio, we recommend that you follow the guided tour.
EiffelStudio for Unix uses the GTK+ theme engine to allow for custom appearance such as changing the default font size and color of windows, etc. If you do not have a theme manager (such as that provided with Gnome) you can copy the .gtkrc-2.0 file from $ISE_EIFFEL/eifinit/studio/spec/gtk directory to your $HOME directory.
Contents
|
| Computer/Processor | UltraSparc. |
| Operating System | Solaris 9.0 or greater for Sparc, Solaris 10 or greater for x86 with either Gnome 2.6 or GTK+ 2.4. |
| C compiler | Sun Studio 12 C compiler |
| Memory | 512MB of RAM (1GB recommended). |
| Hard Disk | 500MB of hard disk space (1GB recommended). |
| Drive | CD-ROM or DVD drive (not required when downloading EiffelStudio). |
| Display | 1024 x 768 or higher resolution video adapter and monitor. |
| Peripherals | Keyboard and mouse or compatible pointing device. |
| ISE_PLATFORM | solaris-sparc for 32 bits version of Solaris on Sparc processor, solaris-sparc-64 for 64 bits versions, solaris-x86 and solaris-x86-64 for the Intel processor on 32 and 64 bits. |
EiffelStudio requires GTK+ 2.4.0 or above to function properly. You can check that you have this installed correctly by typing the following command:
pkg-config --modversion gtk+-2.0
The command should succeed and the version number of GTK+ should appear. If it is not 2.4.0 or above then you cannot continue the installation of EiffelStudio. You first need to install GTK+ 2.4.0.
EiffelStudio requires the library file libmlib.so.2. If this file is missing from your Solaris installation, you can install it by installing medialib.
After downloading the installation package, you should manually extract its contents to your hard drive. For example, you can extract it into /usr/local using the following commands (assuming that you have permission to /usr/local and that the installation package was saved in /tmp/EiffelXX.tar.bz2, where XX stands for the EiffelStudio version):
cd /usr/local tar xvfj /tmp/EiffelXX.tar.bz2
This will install EiffelStudio files into /usr/local/EiffelXX. Once this is done, jump to the Setting up EiffelStudio section in order to complete the installation of EiffelStudio.
Insert the CD into your CD-ROM drive. You should manually extract its contents to your hard drive. For example you can extract it in /usr/local using the following commands (assuming that you have permission to /usr/local and that the CD is mounted on /mnt/cdrom):
cd /usr/local cp -r /mnt/cdrom/EiffelXX .
This will install the EiffelStudio files into /usr/local/EiffelXX. To complete the installation of EiffelStudio, jump to the next section, Setting up EiffelStudio .
Once the files have been installed, you should define the following environment variables in order to run EiffelStudio:
and add $ISE_EIFFEL/studio/spec/$ISE_PLATFORM/bin to your PATH environment variable.
Using sh or bash as a shell, it suffices to type the following commands:
export ISE_EIFFEL=/usr/local/EiffelXX export ISE_PLATFORM=solaris-sparc export PATH=$PATH:$ISE_EIFFEL/studio/spec/$ISE_PLATFORM/bin
Using csh or tcsh as a shell, it suffices to type the following commands:
setenv ISE_EIFFEL /usr/local/EiffelXX setenv ISE_PLATFORM solaris-sparc set path = ($path $ISE_EIFFEL/studio/spec/$ISE_PLATFORM/bin)
If you are using the Enterprise edition, please follow the instructions of the next section, Registering the Enterprise Edition , otherwise jump to the Using EiffelStudio section at the end of this document.
This step assumes you have followed the instructions in the Setting up EiffelStudio section. Perform the following commands to start the registration process:
cd $ISE_EIFFEL
./registerA dialog asking for your Username and CD Key should appear as it does below:
Enter the information located inside the box that contains your copy of the EiffelStudio Enterprise Edition. Once the information is correct, the Register button will be enabled. Click Register to actually register EiffelStudio.
The first time you launch EiffelStudio, you will be asked for an activation key through the following dialog:
By clicking on the http://activate.eiffel.com URL, a new web browser will appear with the requested fields automatically filled in with the appropriate information. Simply click Activate and a new page with an activation code will appear. Copy and paste the activation code in the first field and the Activate button should be enabled to let you activate your copy.
You can activate your copy up to three times. Once you have reached this threshold and need to reinstall your copy, contact Eiffel Software to request one more activation.
If no web browser appears, it is most likely because firefox is not installed on your machine or is not in your path. Instead you should manually launch a new web browser, go to the page http://activate.eiffel.com , and enter the information manually. Then follow the above instructions as if the browser had been properly launched.
You may receive the following dialog when launching EiffelStudio:
This probably means that the register program was not launched or did not succeed in storing data to the following file $ISE_EIFFEL/install/limand/.ec_license. To solve this, rerun the register program with a user account that has permissions to write at $ISE_EIFFEL/install/limand and enter your Username and CD Key.
Once this is done, you can jump to the next section, Using EiffelStudio .
Now everything should be properly installed and you should be able to run the compiler. Launch estudio for the interactive graphical user interface of the compiler, or launch ec for the command line interface. If you are a new user to EiffelStudio, we recommend that you follow the guided tour .
EiffelStudio for Unix uses the GTK+ theme engine to allow for custom appearance such as changing the default font size and color of windows, etc. If you do not have a theme manager (such as that provided with Gnome) you can copy the .gtkrc-2.0 file from $ISE_EIFFEL/eifinit/studio/spec/gtk directory to your $HOME directory.
Here you can find help for installing third party tools and programs which may be necessary for your Eiffel programming needs.
This chapter contains instructions for accomplishing some of the most commonly required tasks in EiffelStudio.
The first thing to do to start Eiffeling is to create a project. Most commands are disabled when no project is created.
When opening EiffelStudio, by default a dialog is popped up that proposes to create or open a project:
Under Create project, several options are offered, which depend on the platform you are on.
All those options are also available in the File/ New project... menu. This pops up a dialog with all the options to generate a new project:
Tip: If you checked the "Don't show this dialog at startup" checkbox in the start-up dialog but want to get it back, you can use the Preferences dialog to reset the default value.
See Also: Retrieving a project from an configuration file
If you have already designed a project and want to retrieve it, or if you want to open a project created by someone else (such as the examples of the libraries which are shipped with EiffelStudio), you can either directly select it from the list of last opened projects or use the Add Project button to open the configuration file.
This dialog also allows you to select which target to compile. A target may be selected from the drop down list by clicking the black triangle. You can also specify your own location where the project will be compiled. The action describes what should be done and the optional clean removes the compiled files of a previous compilation before doing the action.
Reset user settings removes all stored custom information about the project (but not the configuration of the project itself). For example last used target, locations where this project has been compiled, arguments and working directory.
See Also:
Creating a new project
If you know the name of a cluster but not where it is located in the system, there are two ways to find this out:
There are two simple ways to find a class if you know its name or a part of it :
There are many ways to find a feature in a class. In particular :
To find a word or an expression in a text, you can use the search tool . If it is not displayed, you can make it appear by clicking on its icon
in the tool bar. This tool will allow you to search a word or a regular expression and to replace it if you want to. It can be case sensitive and look for isolated words.
Note: The search tool will look for the wanted word in the editor or in the context tool, depending on which one has the focus.
Tip: There are several accelerators that will make it even easier to perform a search. They are detailed in the editor help .
Tip: You can use the quicksearch to search in the current text. Press CTRL + F to get the quick search bar.
There are three kind of tools directly available in a default development tool : Browsing tools on the left, the EiffelStudio Editor on the upper right and context tools on the lower right. No browsing tool, except the feature tool, displays information about a particular component. On the contrary, the editor and context tools display information about a given cluster, class or feature : they are centered on this component. There are several ways to center the editor on an element:
The context tool can be independent from the editor. If it is not, both the editor and the context tool will be centered on the same component. If it is, there is a second address bar , in the context tool title bar. You may then center the context tool on a component by using the three methods described for the editor. You can also center the context tool on the same component as the editor ( the context tool remaining independent): Just click
or select Send to the context tool in the View menu.
To make the context tool independent if it is not, click
or select Isolate context tool in the View menu. To do the opposite, click the same icon or select Merge context tool in the View menu.
To view information about a cluster, you have to center the context tool on this component. Then the metric tool will provide a complete set of measures that you will able to compute.
See Also: See Also
Looking for a cluster
How to analyze a project
Once you centered the editor on a class, you have access to its basic text. If the class is compiled, the features tool shows the list of the features that are defined or redefined in this text. You can also view clickable, flat, flat contract and contract views of the class in the editor. The class tab in the context tool can display more information. If the context tool is independent, center it on the wanted class and select this tab. You can then see information about the features (routines, attributes, exported features, etc. ..) of the class, its ancestors and descendants or its clients and suppliers .
The metric tool provides another kind of data. It allows you to compute a complete set of measures on your class.
See Also:
Looking for a class
Once you centered the editor on a feature, you have access to its text. The feature tab in the context tool can display more information. To have access to it, you have first to center the context tool on the wanted class and select the feature tab. You can then consult the different views of the text of the feature (basic text or flat) and other information such as its callers or its descendant versions.
The metric tool provides another kind of data. It enables you to compute some measures on your feature.
See Also:
Looking for a feature
There are several ways to open a new window. First, you can use the pick and drop shortcut. Then, you can use new window menu items and the corresponding icons. There are three such commands:
Note: Icons mentioned above are droppable: instead of simply clicking on them, you can drop a stone on them. The tools in the new window will then be centered on the corresponding component.
It is possible to create new clusters from EiffelStudio. A dialog window has been designed to help you do so.
There are three ways to make this window appear. You can:
Using this dialog, you can either create a subcluster of an existing cluster or a top-level cluster. If you decide to create a top-level cluster, you should give it a name and a path (if the selected path does not exist, it will be created). You can also choose if it should be recursive or not..
If you want to create a subcluster, give it a name and select its parent in the list of available clusters. Giving it a path is not required. If you do not set a path for a new subcluster, it will be located by default in a subdirectory of its parent cluster, named after the subcluster name. This is the recommended way of creating a subcluster (since its path in the configuration file will be automatically relative to the parent), but it is not compulsory.
To import an existing cluster, you can also go to the Groups section in the Project Settings dialog and click Add cluster. Although this solution may be slightly more tedious, it gives access to more options.
See Also:
Removing a cluster
A dialog window has been designed to help you to add a library to your project.
There are two ways to make this window appear. You can:
Using this dialog, you can either choose a library from a list or select your own library.
A dialog window is dedicated to the creation of new classes.
A list of all the clusters of the system lets you to choose in which one the new class will be inserted. The name of the new class and the name of the corresponding file can be set thank to two text fields above the list. It is also possible to define whether the class should be deferred or expanded, what its creation feature is (if any), what its parents are and whether the default feature clauses should be generated.
Tip: You can change the class text that is generated by default by editing the following files:
$ISE_EIFFEL\studio\help\defaults\$ISE_PLATFORM\full.cls (with default feature clauses) and
$ISE_EIFFEL\studio\help\defaults\$ISE_PLATFORM\empty.cls (without default feature clauses).
To make the window appear, you can:
See Also:
Removing a class
To add a feature to a class, you can directly edit its text of course. EiffelStudio offers you other ways to do so. A dialog window has been designed to help you to add features. Once you make it appear, the new feature dialog allows you to choose what kind of feature you want to create and to set most of its characteristics. The process of creating the new feature is different if it is a procedure , a function or an attribute .
To make the new feature window appear, you can:
This last method does not allow you to create procedures. The first thing to do when the dialog is displayed is to choose the kind of feature you want to create. The rest of the process depends on what you selected : procedure , function or attribute .
Once the new feature dialog is displayed and procedure selected in feature type, follow the following steps:
Once the new feature dialog is displayed and function selected in feature type, follow the following steps:
Once the new feature dialog is displayed and attribute selected in feature type, follow the following steps:
To remove clusters, you can:
See Also:
Adding a cluster
To remove a class, you can:
Warning: Removing a class from the system implies the deletion of the corresponding file on disk.
Warning: Picking a feature and dropping it on the delete icon, or calling Remove current item as the editor is centered on a feature, will not remove the feature but the class to which it belongs.
See Also:
Adding a class
To remove a feature, you may of course delete the corresponding lines in the class text. You can also use the Diagram tool if it is an attribute or a function. To do so, make sure that supplier links are shown in the diagram (if
is not pressed, click it). Pick the link that correspond to the feature you want to remove and drop the pebble on
.
See Also:
Adding a feature
To move a class from a cluster to another one, you have to use the Diagram tool. First, center the tool on the cluster that contains the class you want to move. Then, if the destination cluster is not shown on the diagram, pick it in the groups tool and drop it in the diagram. Once both clusters are displayed, you just have to drag the class to its destination.
See Also:
Find where a class is
Find where a cluster is
A tool has been designed to help you to modify the settings of your project. To make the Project configuration tool appear, there are two possibilities:
This tool will allow you, for instance, to add or remove clusters, set the assertion level or activate debug clauses. For more complete information, please refer to the Project configuration tool help .
There are several ways to compile an executable with EiffelStudio.
The most essential compilation modes are: melting, freezing, and finalizing. To learn more about the compilation semantics in EiffelStudio, see the documentation of Eiffel's compilation technology.
There is a command for each compilation mode in the Project menu, under the entries Compile, Freeze and Finalize.
The "drop-down" option of the Compile button (
) on the Project toolbar also offers these choices as shown in the image below.
If you need the compilation options even handier than this, you can customize the Project toolbar by adding icons for each of the options:
,
,
. Here's how. Or you can use the keyboard shortcuts that are shown in the Compile button's drop-down menu.
To help resolve the errors that occur during the Eiffel compilation, use the compilation error wizard. For errors occurring during the C compilation, check that the installation is not corrupted and refer to your C compiler documentation for more information.
See Also:
Command line options
Compiler
There are two main types of libraries in Eiffel: precompiled Eiffel libraries and C libraries. Both kinds of libraries can be created via EiffelStudio. The former can only be used in Eiffel projects, C libraries can be used either in Eiffel programs, or in standard C programs.
To generate an Eiffel precompiled library:
or
To generate a dynamically linked C library using Eiffel code:
The generated C library should be located in the EIFGENs|target_name|W_code directory in the directory of your project.
To generate a C library from a C compiler, please refer to the documentation of your C compiler.
See Also:
Using libraries
CECIL library: calling Eiffel routines from C programs
Command line options
To modify the assertion level in a generated binary (executable or library),
See Also:
Assertions in Eiffel
The specification of the Eiffel programming language has remained largely static over its life, arguably due to its sound initial design. Still, on occasion there will be significant value in evolving Eiffel and adapting it to new challenges. To accommodate this evolution, the Eiffel Software compiler provides a set of compilation variants which offer a balance of syntax support. This starts with compatibility with previously valid syntax, moves through the latest standard, and forward to language features which are currently supported but not yet etched into the standard.
EiffelStudio project settings supports four of these syntax compilation variants:
Because the language, and by necessity the compilation technology too, may at times be a moving target, it is difficult to give precise definitions of what these variants mean at any given time. Today's valid identifier is tomorrow's keyword and vice versa.
Recommended: It's always a good idea to check the EiffelStudio release notes and Differences between standard ECMA-367 and Eiffel Software implementation when you install a new version to see if new language elements are supported or existing ones have been made obsolete.
Additionally, you can see more detail on how these variants effect certain words in a particular version by checking the syntax level variant settings by version.
Even so, we can use an example from a particular point in time to show the basic idea. At one time, the word indexing was a keyword, and the word note was available for use as a valid identifier. But there came a time that due to a consensus of opinion within the Eiffel standards committee, the role of the keyword indexing was replaced by a new keyword note. This meant two things. First that if you had used the keyword indexing in your classes (and who hadn't?), then at some point you would want to change those occurrences to note. Second, if you had used the word note as an identifier, then at some point you would have to change your code to use a different identifier it its place.
The Eiffel compiler is savvy enough in some cases to delay the necessity of these changes by considering code in its current context. For example, if a particular keyword is not appropriate in a certain context, then it is only reasonable that when the word is used in that context, it is used as an identifier. But sometimes ambiguities arise that the compiler cannot resolve by analyzing context. It is in these cases that the syntax variants are useful.
So, considering the transition from indexing to note, here are the effects of the first three variants:
When Provisional syntax is selected, it allows the use of certain language constructs which, although supported by the Eiffel Software compiler, may not yet be stamped into the standard (or at least approved for the standard by a consensus of the standard committee). For example, version 6.6 of EiffelStudio includes support for the iteration form of the Eiffel loop construct, which at the time of the release is not yet approved for inclusion in the ISO/ECMA standard ... although it is expected, with reasonable confidence, to become standard in the future. Of course, there is always the risk that, once standardized, the syntax may change some, so selecting Provisional syntax is an acknowledgment of this risk when non-standard language elements are being used.
To set the syntax variant, open Project Settings. Then find the general setting Syntax for the target or group of interest. The value field for Syntax will give you a choice of the available variants when clicked. Select the appropriate variant, then, click OK.
To profile an executable, the profiler must first be enabled. To enable the profiler:
See Also:
Profiler wizard
There are two kinds of libraries in Eiffel: precompiled Eiffel libraries and C libraries.
To use an Eiffel precompiled library:
Note: You can only use one precompiled library at a time in a project. To use more than one, you should precompile all the libraries you want to use together in a single precompiled library.
To use a C library:
See Also:
Creating libraries
Adding classes and clusters from Eiffel libraries without precompiling the library
Making C calls in Eiffel
The best way to speed up a program is of course to improve the algorithms and data structures you are using. Spotting the functions that slow down the execution and improving can change a lot in a program. Profiling can be used for this.
Try to keep the number of classes and objects in your system as low as possible to ensure maximum efficiency. This should never hinder the design of the system, though.
You can also use the functionality provided by the MEMORY class to tweak the garbage collector behavior according to your needs. However, be careful with this, since providing erroneous parameters might lead to memory leaks, huge memory consumption, or on the contrary a dramatic slow down of the application. If you are not entirely sure what a parameter is for, avoid changing it. The default values should fit for most standard applications.
On top of that, EiffelStudio provides powerful optimizations, some being done automatically, others being configurable. To obtain a maximum efficiency, it is recommended to Finalize your program from scratch and without using precompiled libraries.
In the Project Settings dialog advanced section , try experimenting with the Inlining option, and setting the maximum size of features that should be inlined. Only Eiffel features are inlined by this option, to see how to inline the C functions you may be using in your program, please refer to your C compiler documentation.
In the Project Settings dialog advanced section , enabling the Dead code removal will help produce smaller executables.
Removing the Execution Trace will optimize the executable in size and speed, but in case of crash no information will be available.
All these options are located in the Project Settings dialog, in the Advanced section. They are only effective during finalizations.
See Also:
Profiler wizard
Eiffel supports multithreaded programs. The EiffelThread Library provides ways to handle threads safely inside an Eiffel program. Make sure you add it to your project if you want to use threads.
To create a multithreaded program or library:
Warning: Make sure the external and precompiled libraries you use have also been compiled with support for threads.
See Also:
Creating libraries
Doing a clean compile, sometimes called a compile from scratch, is occasionally necessary as you develop systems. For example, if you change certain project settings or add, remove, or change a precompiled library, you will have to do a clean compile.
The process first involves cleaning, that is, removing any of the previously generated intermediate compile information (the EIFGENs folder). Cleaning is followed by a fresh compile which regenerates the EIFGENs anew.
You can only do a clean compile by closing EiffelStudio on your project, then restarting it and requesting the clean compile when EiffelStudio reopens.
So, for example, if you need to change precompiled libraries, you would open project settings, remove the old precompiled library, and add the new one. Then you would quit EiffelStudio and restart it. When the EiffelStudio dialog appears, select your project and Action: Compile and check the Clean box, as shown in the figure below. When you click Open EiffelStudio will do a clean compile of your project.
There are several ways to launch an application. Not all are available depending on the way you compiled your system.
Melted and frozen executables can be debugged. Several methods can be used to launch such an executable:
Tip: All the above commands can be accessed either in the Project toolbar or in the Debug menu.
They can be used either to launch the program or to resume its execution after it has been paused.
Finalized executables can also be run, but they are not debuggable and cannot be interrupted. To run a finalized executable, use the Run a finalized executable , located in the Project menu and the Project toolbar.
See Also:
Compiling an executable
Using breakpoints
Interrupting an application
There are two ways a debugged application can be interrupted: its execution can be paused, or it can be killed.
Two methods can be used to pause a debugged application:
To kill a debugged application, use the Stop a debugged application , located in both the debug menu and the project toolbar.
See Also:
Running a program
Using breakpoints
To view the dynamic state of a debugged application, just stop it at the point where you want to see its context. The debugger tools will automatically be popped up then, yielding the call stack of the application, as well as the state of the objects located in the object tree, which include at least the object corresponding to the level of the call stack where the call stack cursor
is.
To see at which point the features in the call stack have stopped, just click the feature on which you want this information in the call stack. Doing this will change the cursor position in the call stack and display the flat view of the feature in the context tool.
To follow an object state between pauses of the application, pick and drop it into the object tree, which will make it stay in it.
You can also query features dynamically by using the evaluation tool, which can be very useful to have glimpses of the C memory of the system, for instance.
See Also:
Pausing an application
Call stack tool
Object tool
Evaluation tool
To change the status of one breakpoint, it is possible to use the breakpoints menu , which changes the state of a single breakpoint at a time.
To change the status of several breakpoints at the same time, the easiest way is to use the breakpoints-related commands , which have actions at feature-scope, class-scope and system-scope.
See Also:
Running an application
Interrupting an application
Breakpoints reference
It is possible to raise and catch exceptions in Eiffel. Catching exceptions is done by using the rescue keyword. The EXCEPTIONS class provides helper features to analyze the caught exception and handle it.
The EXCEPTIONS class also provides ways to raise exception, via its feature raise .
When an exception is raised while the application is being debugged, the application stops immediately and the debugger displays the context in which the exception occurred, whether or not the exception is rescued.
See Also:
Reference of exceptions
Eiffel provides ways to add debug code to features to help during their debugging. You may think of it as the well-known C construct:
#ifdef MY_DEBUG_FLAG/* Debug code is here */ #endif
The corresponding construct in Eiffel is provided by the debug keyword. It is possible to wrap code inside a debug clause like this:
debug("MY_DEBUG_FLAG") -- Debug code is here. end
It is then possible to enable or disable debug clauses globally.
To modify the debug clauses status:
Tip: Debug clauses make it easy to remove all debug messages when finalizing a system.
To debug a program that uses command line parameters, it is possible to have the debugger call the generated program with certain command line arguments automatically.
To change the command line arguments used when debugging:
Tip: To get the command line arguments in a program, it is possible to either define the root feature as taking an array of STRING_8 objects, or to use the ARGUMENTS class, which provides a lot of functionality linked with command line arguments.
The profiler is a tool that gives dynamic execution time information. It is very useful to detect which parts of a program need to be optimized most.
To use the profiler, the first thing to do is to enable it.
To enable the profiler:
By default the profiler will profile the entire program. However it is possible to enable or disable the profiler on certain clusters only. To do this:
It is also possible to dynamically start and stop the profiler in a program. To do this:
Tip: To profile only part of a program, turn off the profiler at the very beginning of the program, turn it on just before the part of the code that should be profiled, and turn it back off after this section. Typically, it results in the following code:
In the root feature:
local ps: PROFILING_SETTING -- Other local variables if necessary. do create ps.make ps.stop_profiling -- Real program execution. ps.start_profiling end
And in the feature(s) that needs to be profiled:
local ps: PROFILING_SETTING -- Other local variables if necessary. do create ps.make ps.start_profiling -- What needs to be profiled. ps.stop_profiling end
Note: Even if the profiler should only work in certain sections of code, the Profiling check box of the Projects Settings dialog must be checked or the profile option must be set on certain clusters.
Once the profiler has been enabled and the program has been recompiled, it is necessary to launch the program.
Tip: It is possible to profile debuggable(frozen/melted) executables as well as finalized ones. It is more interesting to profile finalized executables, though, since the execution speed is more representative of what will be obtained by your end users.
When the program exits, a file named 'profinfo' should be generated next to it.
All that's left to do is launch the Profiler wizard and follow the instructions.
See Also:
Generating executables
Running a program
Tuning a program
Contents
|
The tracing facility allows you to see a structured log of the flow of control through your system, feature by feature. By default, execution traces are written to standard output.
Note: The tracing facility is not supported on the Microsoft .NET platform.
You can make tracing usable for a particular cluster by setting the Trace setting to True in your project settings for a particular cluster.
To do this:
This will cause a trace entry to be written to the console for any feature execution on a class in the cluster(s) you selected for tracing. To get a feel for this, look at the following trace outputs, built on the default Eiffel application ("Hello Eiffel World!).
First, here's what the "Hello Eiffel World!" output looks like without using the tracing facility.
Next, here's the output when the Trace project setting is set to True on the root cluster.
Last, here's the output when Trace is True for both the root cluster and EiffelBase.
It is also possible to enable and disable the trace dynamically. To do this:
Tip: To enable tracing on only part of a system, disable tracing at the very beginning of the program, enable it just before the part of the code that should be traced, and then disable it again after this section. The code below illustrates this tip.
In the root feature:
local ts: TRACING_SETTING -- Other local variables if necessary. do create ts.make ps.disable_tracing -- Program execution continues. ... -- Restore tracing before exiting for proper cleanup. ps.enable_tracing end
Then, in a feature in which tracing is desired:
local ts: TRACING_SETTING -- Other local variables if necessary. do create ts.make ps.enable_tracing -- Enable trace -- Section needing trace. ... ps.disable_tracing -- Disable trace end
Warning: Enabling/disabling tracing as shown above has to be done within the same routine otherwise the computed depth would be inaccurate and this would cause some unpredictable results.
You can do more complex tracing tasks by using a trace handler. The deferred class TRACE_HANDLER contains a deferred feature trace which you can effect in a descendant of TRACE_HANDLER. Your effective version of trace will be called whenever a trace event occurs. {TRACE_HANDLER}.trace looks like this:
trace (a_type_id: INTEGER; a_c_class_name, a_c_feature_name: POINTER; a_depth: INTEGER; a_is_entering: BOOLEAN) -- Trigger a trace operation from a feature represented by `a_c_feature_name' defined in -- class `a_c_class_name' and applied to an object of type `a_type_id' at a call depth `a_depth'. -- If `a_is_entering' we are entering the routine, otherwise we are exiting it. require a_type_id_non_negative: a_type_id >= 0 a_depth_non_negative: a_depth >= 0 deferred end
You may notice in the specification for trace above that the arguments representing the class and feature names are of type POINTER (versus some variant of STRING).
To make this facility more approachable for common tasks, EiffelBase also contains another class, a deferred descendant of TRACING_HANDLER, called STRING_TRACING_HANDLER in which the trace feature's arguments for class and feature names are strings, and the argument for type is an instance of TYPE rather than an integer type id as in TRACING_HANDLER. {STRING_TRACING_HANDLER}.trace looks like this:
trace (a_type: TYPE [detachable ANY]; a_class_name, a_feature_name: detachable STRING; a_depth: INTEGER; a_is_entering: BOOLEAN) -- Trigger a trace operation from a feature represented by `a_feature_name' defined in -- class `a_class_name' and applied to an object of type `a_type' at a call depth `a_depth'. -- If `a_is_entering' we are entering the routine, otherwise we are exiting it. require a_depth_non_negative: a_depth >= 0 deferred end
Suppose we wanted to write trace long entries in a private log file for the entry and exit of a number of routines during the run of a simple application. We could create a descendant of STRING_TRACING_HANDLER that looks like this:
class EXAMPLE_HANDLER inherit STRING_TRACING_HANDLER feature trace (a_type: TYPE [ANY]; a_class_name, a_feature_name: STRING_8; a_depth: INTEGER_32; a_is_entering: BOOLEAN) -- <Precursor> do trace_log_file.put_string (create {STRING}.make_filled ('>', a_depth)) if a_is_entering then trace_log_file.put_string (" Is entering " + "{" + a_class_name + "}." + a_feature_name + "%N") else trace_log_file.put_string (" Is leaving " + "{" + a_class_name + "}." + a_feature_name + "%N") end end trace_log_file: PLAIN_TEXT_FILE -- Log file once create Result.make_open_write ("my_log_file.txt") end close_log_file -- Close log file do trace_log_file.close end end
In EXAMPLE_HANDLER the procedure trace is effected to write the desired information to the log_file.
Then we could use EXAMPLE_HANDLER in a class that might look like this:
class APPLICATION create make feature make -- Run application. local tracing_setting: TRACING_SETTING tracing_handler: EXAMPLE_HANDLER do create tracing_setting tracing_setting.enable_tracing create tracing_handler tracing_handler.activate call_depth_one tracing_handler.deactivate tracing_handler.close_log_file tracing_setting.disable_tracing end call_depth_one -- Call depth one routine do call_depth_two end call_depth_two -- Call depth two routine do call_depth_three end call_depth_three -- Call depth three routine do end end
In {APPLICATION}.make, the instances of TRACING_SETTING and EXAMPLE_HANDLER are created. Tracing is enabled and the handler is activated. After the section of interest, the handler is deactivated, the log file closed, and tracing disabled.
Now consider a system in which {APPLICATION}.make is the root, APPLICATION is the only class in the root cluster, and that the project setting Trace is true for the root cluster only. After running the system, the content of my_log_file.txt would be:
> Is entering {APPLICATION}.call_depth_one
>> Is entering {APPLICATION}.call_depth_two
>>> Is entering {APPLICATION}.call_depth_three
>>> Is leaving {APPLICATION}.call_depth_three
>> Is leaving {APPLICATION}.call_depth_two
> Is leaving {APPLICATION}.call_depth_one
Tip: To make sure all your changes are in the diagram, perform a compilation.
Almost all actions in the diagram tool are undoable. Every action that can be undone, can also be redone. For advanced undoing, open the history tool.
Tip: Undo actions cannot be undone. Use redo to undo an undo action.
Note: When an action is performed that cannot be undone, the history tool is emptied.
See Also:
Creating a new class using the address bar
To create a new feature just add a new client link in the diagram.
See Also:
Adding a feature
Refactoring actions include renaming classes and features, and relocating features to an ancestor class. Refactoring actions start with a compilation and also end with a compilation. Refactoring has a separate undo functionality which allows you to undo a refactoring action as long as no changes have been made to the classes that have been refactored.
The Refactoring toolbar contains holes for both the Rename (
) and Pull up (
) refactoring actions. So, if the Refactoring toolbar is visible, you can "pick" a feature, for example, and drop it onto one of the refactoring holes. If the Refactoring toolbar is not visible, you can make it visible or you can access refactoring actions through the context menu associated with a class or feature name (right-click to see the context menu, or shift-right-click if you are in "pick-and-drop by default" mode).
Warning: An action that deletes one or more files or directories cannot be undone!
Tip: Turn on Automatic backups. EiffelStudio will make a copy of each class file every time a compilation is done.
See Also:
Removing items from the view only
Note: This action will also add the parent in the class text.
See Also:
Creating client/supplier links
See Also:
Creating aggregate client/supplier links
Creating Inheritance links
New feature dialog
See Also:
Creating client/supplier links
Creating Inheritance links
New feature dialog
If you do not want straight arrows, you can insert handles on them. It is recommended that you use the link tool to do this, because it inserts the handles so that the angles in the line are exactly 90 degrees.
The combinations of handles you can apply to your link are:
Once you have created a link to show the relationship between the classes in your system you may wish to organize them. One technique for doing this easily is to create handles in the links. A handle is simply a point anywhere along the link that causes the link to change direction. To create a handle just click the mouse at the exact point on the link you wish to put the handle and then drag it to where you want the handle to be positioned in the overall diagram. You can create as many handles as you wish and use them to organize you diagram so that it is easier to interpret and so that links do not get too jumbled and become incoherent.
Note: If you want to remove the item from the system, use the Delete hole.
Tip: If the entire cluster is of no relevance to your diagram, hide it from the view altogether.
Tip: Lower quality display is faster for drawing so is recommended for very large diagrams.
Tip: The particular configuration of the classes in your system when using the physics mode is determined by the various settings in the Physics Setting Dialog .
Tip: To see the effects of anchoring turn on physics mode and then anchor a class as described above. Now open the physics settings dialog and adjust the sliders. In the diagram you will see all anchored classes do not move whilst those surrounding them adjust to the new settings.
Tip: To see the effects of each parameter modify it whilst your diagram is in view and you will see the diagram adjust to the new settings dynamically.
Tip: Use the cluster legend also to quickly see sub-cluster organization within your overall cluster design.
The metric tab in the context tool allows project analyzing. Built on a suitable metric theory, this tool provides a set of elementary metrics that can be evaluated to test projects design and implementation.
The metric tool provides an interface to evaluate measures, save them or delete some of them when no longer needed.
The metric interface allows users to analyze their projects. It provides a set of metrics that could be evaluated over various scopes to obtain quantitative information about systems.
Thanks to the metric interface, users can evaluate metrics over different scopes, get some detailed information when possible, save the pertinent measures, delete the useless ones, and update the values of previously recorded metrics.
Below is the list of operations you can perform.
To evaluate a metric over a scope:
You can get more information about the evaluated metric. See detailing a measure .
Warning: When calculated, a measure is not saved.
See Also:
Saving a measure
Detailing a measure
To save the result of evaluation of a metric:
See Also:
Evaluating a measure
Detailing measures
It is possible to have some details when evaluating a metric.
See Also:
Evaluating a measure
Saving measures
The metric tool ("Metric" tab of the context tool) provides by default a set of metrics that can be used to make some measurements over various scopes in order to evaluate a project.
This set of metrics is certainly not complete, users may probably want to define other metrics regarding their own needs. And then, since needs are different and in order to avoid an explosion in the number of basic metrics, we agreed on implementing only elementary metrics that could not be evaluated if not implemented in the tool.
Users can then define their own metrics. The metric tool provides an interface to define new metrics. Click on the Metric Definition tab in the metric tool to start adding new metrics and modifying existing metrics.
The metric interface provides by default a set of basic metrics. However, user may want to define other metrics, such as linear sums or different ratios, or combining some criteria... This is possible thanks to the Metric Definition tab of the metric tool.
New metrics are increasingly added to the list of metrics which is ordered by unit type, and are available for calculation .
See Also:
Evaluating a measure
Managing new metrics
To define a derived metric, you must select the Metric Definition tab and click the New metric button. A menu appears asking you the kind of metric you want to define. Select Basic metric and then the type of the results you are looking for (i.e. Class, Feature, Line, ...). Once done, you can perform the following steps:
STRING if the criterion you have is to look for descendants of the STRING class).
For more information about criterion, read the Managing criterion section.
A summary of the metric you just defined appears in a textual representation in the Expression text field.
See Also:
Managing metrics
Managing criterion
To define a linear metric, you must select the Metric Definition tab and click the New metric button. A menu appears asking you the kind of metric you want to define. Select Linear metric and then the type of the results you are looking for (i.e. Class, Feature, Line, ...). Once done, you can perform the following steps:
A summary of the metric you just defined appears in a textual representation in the Expression text field.
See Also:
Managing metrics
To define a ratio metric, you must select the Metric Definition tab and click the New metric button. A menu appears asking you the kind of metric you want to define. Select Ratio metric. Once done, you can perform the following steps:
A summary of the metric you just defined appears in a textual representation in the Expression text field.
See Also:
Managing metrics
After having defined some new metrics, it is possible to delete the useless ones, or to edit them:
The archive file for a system contains all the values of measures resulting from evaluating selected metrics. It also contains the definitions of non elementary metrics (the one user has defined) in order to be sure of what is being measured.
The archive files are entitled to achieve comparisons between systems. And then, user can compare systems to evaluate their own projects.
Users may want to archive the result of the system they are working on. To create an archive is basically the same as saving a measure .
See Also:
Comparing to an archive
The main goal of archives is comparing archives one to another. In order to compare your project to an archived file, you must select the Metric archive tab of the metric tool.
The goal is to load the archive of a (preferably different) project, to compare the archived measures to the system's. You can select your current archive or any other archive, against a reference archive file.
Once the archives are selected, click the Compare button to start the comparison. It will bring you to the Detailed Result tab.
See Also:
Creating an archive
EiffelStudio can generate documentation for a system using many different formats.
The Documentation Wizard, which helps you to get the documentation you want, is available in the Project menu, under the entry Generate Documentation.
The first page of the Documentation Wizard lets you choose between the available formats for the documentation:
Tip: The nicest output is produced by the html-stylesheet format.
Now the wizard asks you to select the clusters you want to produce documentation for:
In the next page you can specify indexing items on which HTML metatags will be based:
Note: This page is only available for HTML documentation.
You can then pick the formats you need among those available. For example, you might need a file containing the Cluster hierarchy of your system or, for each class, a file containing the Contracts of that class. At this point you can also decide to generate BON diagrams for the clusters selected in the previous page.
If you have checked Cluster diagrams in the previous page, you will now be able to choose a view for each diagram that is going to be generated. You have the choice between an automatically arranged view and all of the views you may have manually arranged with the Diagram Tool .
Note: Cluster diagrams are only available for HTML documentation.
Here comes the last page; you can choose the directory where the documentation is going to be generated:
See Also:
Generating XMI documentation
EiffelStudio can generate an XMI description of a system; XMI (XML Metadata Interchange) format is the new industry standard way to describe and exchange object-oriented systems, further information can be found here .
The XMI Export wizard is available in the Project menu, under the entry Export XMI.
The first page of the wizard lets you select the clusters you want to produce documentation for:
On the second and last page, you can choose the directory where the XML file is going to be generated:
See Also:
Generating multi-format documentation
Some of the EiffelStudio Editor properties are customizable. Automatic completion, for instance, can be partially or totally disabled, and inserted strings can be defined by the user. Some accelerators are customizable too. For more information, please refer to the editor preferences reference .
See Also:
Text colors and font customization.
By modifying EiffelStudio preferences, you can change the font and the colors used to display texts in the editor. For more information, refer to EiffelStudio graphical preferences reference .
See Also:
Customizing formatted output
There may be up to 26 buttons in the standard toolbar and up to 17 in the project toolbar . All those buttons are not shown by default though. Only 16 icons are displayed in the default standard toolbar for instance. It is possible to choose which button are shown and in which order they appear in the toolbars. To do so, use toolbar customization windows. they appear when you choose Customize standard toolbar... or Customize project toolbar... in the toolbars sub-menu of the View menu or in the contextual menu of the toolbars (which is displayed when you right-click in the empty space on the right of the toolbars).
See Also:
The toolbars and their buttons
Toolbars customization windows
Update Needed: what it means.
By default, the EiffelStudio Editor and the context tool are centered on the same cluster, class or feature. It is possible to make the context tool independent from the editor. It has then its own address bar and can display information on a totally different component than the one on which the editor is centered.
To do so, click on or select Isolate context tool in the View menu. To go back to the previous configuration, click on the same icon again or select Merge context tool in the View menu.
You can also modify the EiffelStudio preferences so that next time a window is opened, its context tool will be automatically independent: open the preferences window by choosing Preferences... in the Tools menu. Select then the "context tool" sub-category in the "Tools" of the preferences tree. Lastly click on "Share addresses between the editor and the context tool" and set it to False.
Click on save and exit to complete the change.
See Also:
Preference window overview
EiffelStudio preferences
By default, there may not be more than 10 items in the history of a development window. It means that combo boxes in the address bar will let you choose between at most 10 possibilities. You can change this number. To do so, use the preference window : select Preferences in the Tools menu. Then in the preferences tree, select the "Browsing tools "sub-category in the "Tools" category. On the right part of the window, a list of preferences will appear, including "number of items displayed in the history combo boxes". Click on this item and enter the new value.
Click on save and exit to complete the change.
See Also:
Preference window description
EiffelStudio preferences
Every class in your system inherits from ANY. INTEGER, like other classes that represent basic types, is very often a supplier of the classes the user wrote. It may therefore not be interesting to display classes such as ANY or INTEGER in BON diagrams.
EiffelStudio allows you to customize a list of classes that it has to ignore when it creates diagrams. This list is stored in the EiffelStudio preferences . To modify it, first open the preferences window by choosing Preferences... in the Tools menu. Select then the "context tool" sub-category of the "Tools" category in the preferences tree. On the right, you will then see a table of preferences, which includes "Show ALL classes in the diagram" and "Names of classes that should not appear in generated diagrams". If "Show ALL classes in the diagram" is not False, click on it and set it to False. Then click on "Names of classes that should not appear in generated diagrams" and edit the list. Class names must be separated by semicolons.
After modifying the list, click on save and exit to complete the change.
See Also:
Preference window description
EiffelStudio preferences
It is possible in EiffelStudio to customize some properties of class text views (other than basic texts) displayed in the editor or class and feature tabs of the context tool. Besides graphical appearance, you may modify:
feature clauses.
note clauses that should not be displayed.
These properties are set in the EiffelStudio preferences. You can modify them in the preferences window. To open this window, select Preferences... in the Tool menu. Then select the "Context tool" sub-category of the "Tools" category in the preferences tree. Click then on a preference on the right to modify its value. Click on save and exit to complete the changes.
See Also:
Preference window description
EiffelStudio preferences
By clicking on, or by dropping a pebble on the external editor toolbar button(
), you can launch an external editor. By default, this editor is VI on Unix and Notepad on Windows. You can tell EiffelStudio to launch another editor by editing the preferences.
To do so, first open the preferences window by choosing Preferences... in the Tools menu. Select then the "Global preferences" category in the preferences tree. Click on "Command used to launch an external editor" and modify the command line so that it calls your favorite editor. You can use keywords that represent the filename ($target)and the line number ($line) as is explained in the preferences reference .
After modifying the command line, click on save and exit to complete the change.
See Also:
Preference window description
EiffelStudio preferences
Contents
|
By configuring external commands, you can set up EiffelStudio to execute a few basic commands for Subversion or other source code management (SCM) systems. Source code management systems, sometimes called revision control or version control systems are often used as part of a software configuration management strategy to track and control changes to software and its supporting documents.
You can define external commands by using the external commands editor dialog. Then you can execute those commands through the Tools menu or with keyboard shortcuts.
Note: The notation used in the examples on this page will work for Microsoft Windows. Other platforms may require different command formats.
Suppose that you want to add an external command to EiffelStudio to Subversion's update command (update brings your working copy up-to-date with the repository). You can define a command with an appropriate name, say svn update, as shown below.
The command line:
svn up $file_name
MY_CLASS which exists in file my_class.e, then that file name would be used in the Subversion update command executed.
Once the command is defined, it will be accessible through EiffelStudio's Tools menu, either by selecting it explicitly or by using its associated keyboard short cut, Alt+0, in the case of this example.
You can use this same technique to add external commands for other Subversion commands that require only a basic form. For example, to create a command that will add the file for the currently edited class to the repository, add a new external command with the command line:
svn add $file_name
or, to revert local changes to the file associated with the class which is currently the target of the editor:
svn revert $file_name
It's possible that in some cases, for example that of svn revert, you might want to have the command provide you with a chance to back out of the deal before the command actually executes. You can do this by adding a little more to the command line:
Here the command line:
echo Revert changes to $class_name? && pause && svn revert $file_name
first asks for confirmation before executing the command.
When you execute this command you will see the confirmation prompt in EiffelStudio's Console tool:
If you choose to execute the command, then just press return. If you have second thoughts and want to cancel the command, then do so by clicking the Console tool's stop button (
).
If you are using the TortoiseSVN GUI client for Subversion on Microsoft Windows, you may prefer to have TortoiseSVN execute the Subversion commands for you from EiffelStudio. You can do this by starting tortoiseproc.exe, and providing the specifics for each command as shown in Appendix D of the TortoiseSVN documentation.
Some common Subversion command invocations are shown with their respective command lines below:
| Subversion command | Command line |
| revert | start tortoiseproc /command:revert /path:"$file_name" /notempfile |
| commit | start tortoiseproc /command:commit /path:"$file_name" /notempfile |
| log | start tortoiseproc /command:log /path:"$file_name" /notempfile |
| diff | start tortoiseproc /command:diff /path:"$file_name" /notempfile |
This is a guided tour of Eiffel Software's EiffelStudio interactive software development environment.
EiffelStudio is the central tool of Eiffel Software's implementation of Eiffel, letting you design, develop, debug, document, measure, maintain, test, revise and expand systems using the full power of object technology and Design by Contract™.
This guided tour introduces the essential properties of EiffelStudio. It will take you through a tour of the environment, using a pre-existing example system.
Contents
|
Although it skips many specific or advanced facilities, this Tour will help you quickly become familiar with the way you can use the environment for your work. After reading it you will know the basics of working with EiffelStudio:
The most important property to keep in mind as you are discovering EiffelStudio is that it is neither just a "programming environment" nor just a "CASE tool" (Computer-Aided Software Engineering) for analysis and design. It encompasses both of these functions and many others. Most system builders today are used to a dichotomy between the high end and the low end:
Keeping these tools separate is, however, detrimental to the quality of the software process and the resulting products. If they are in the hands of different teams, communication problems may arise, leading to discrepancies between need and realization; this can be a source of bugs or even project failure. If it's the same people using tools of both kinds, they have to keep switching notations, tools and modes of thinking. The use of different frameworks at both ends makes it difficult to keep the high-level model and the implementation consistent; too often, a change decided at the implementation level is not reflected back in the higher model. After a while, the system gets into the state of disorder and inconsistency that good tools are precisely meant to avoid.
EiffelStudio, in line with the principles of seamless development and reversibility of the Eiffel method, removes the gap by providing a single set of tools that accompany you throughout a project, from the most high-level initial stages to the most low-level aspects of implementation and maintenance.
This generality is reflected throughout the environment by, for example, the dual use of text and graphics. As another example, you should think of the EiffelStudio compiler, not just as a tool for executing Eiffel software in its final form, but also, thanks to its extensive validity checking facilities, as a design consistency tool that performs many verifications commonly associated with CASE tools.
Depending on your project needs, you may take advantage of EiffelStudio's versatility to address specific purposes:
If you have access to EiffelStudio as you read this Tour, the most effective technique is to execute all the suggested operations as you read about them.
Please execute user actions, such as clicking, only when asked to do so.
This Tour assumes very little about what you know and what you don't.
It does assume that you can do simple manipulations on your platform of choice, such as: on Windows, finding and drag-and-dropping folders and files in the Windows Explorer; on Unix, changing to a certain directory ( cd ) and listing the files of a directory ( ls ).
The more you already know about object technology and object-oriented environments, the better. But remember, if you have used other environments before, keep a fresh outlook; EiffelStudio is different, and it may take a while before you fully understand why it does some things in a certain way.
EiffelStudio is one of the most portable environments in the industry, running in an almost identical fashion on Windows, on the new Microsoft .NET environment, on many variants of Unix, on Linux, on OpenVMS.
Once an EiffelStudio session has been started, you can largely forget about the operating system. But a few operations -- mostly at the beginning, to launch EiffelStudio -- require platform-dependent mechanisms: starting a program, traversing the file structure, selecting a file. These cases will be marked accordingly below.
Windows users should particularly note the following two conventions of terminology:
c:\d1\d2\f . This example uses the Windows notation, which separates successive components of a path name by a backward slash character \ . On Unix and Linux, the separator is a forward slash / , as in /d1/d2/f ; this is also the convention on the Internet for denoting addresses (URLs). Most file names in this manual appear in this Unix/Internet style. On Windows you will normally have to use the backslash convention, although EiffelStudio also accepts forward slashes. In any case you must be consistent: don't mix backward and forward slashes in the same path name. Also note that some names, such as those of object files to be linked with your system, will be passed to outside tools -- C compilers, loaders -- that may not accept the forward slash.
OpenVMS users may similarly use either the Unix convention or the specific OpenVMS path naming convention.
If you are a one-platform person, just ignore, for the next few pages, all references to any platform other than your heart's favorite. They will quickly go away.
To run the example you must have installed EiffelStudio and set up the environment. Check in particular the following:
ISE_EIFFEL must be set to the installation directory, and the environment variable ISE_PLATFORM to the platform. On Windows this is taken care of automatically by the installation procedure, but on Unix/Linux and OpenVMS you must update your path and environment manually. Throughout this discussion the notations $ISE_EIFFEL and $ISE_PLATFORM will refer to the values of these variables -- the installation directory, and the platform. (The Windows notation would be %ISE_EIFFEL% and %ISE_PLATFORM%.)
Please take a moment to locate the example files on your installation. They all appear in the following directory, part of the Eiffel delivery:
$ISE_EIFFEL/examples/studio/tour
(Windows users: remember that instead of the slash / your platform uses a backslash \ . OpenVMS users: this is to be replaced by the OpenVMS path naming conventions.)
See Also: For a quick introduction to EiffelStudio, see the online EiffelStudio presentation available on the Eiffel Software developers' presentations web page.
Note: If you are using Eiffel on a personal computer, you have the option of working directly in the installation directory and would not necessarily need to make copies of files as per the present section. If you choose to work directly in the installation directory, skip this section and go on to the next section, Starting EiffelStudio and Opening a Project. If you work under Unix or OpenVMS, or may have to share the Eiffel installation with other users, do not have write permissions on the installation, or want to keep the installation unchanged, then please do read the present section and apply its instructions.
If you are going to work on a copy, choose or create a directory of your own; let's call it YOURDIR for the rest of the discussion.
To copy all the files of the example to YOURDIR:
$ISE_EIFFEL\examples\studio\tour , select all the files in that directory, and drag-and-drop them to YOURDIR .
cp $ISE_EIFFEL/examples/studio/tour/* YOURDIR
copy $ISE_EIFFEL:[examples.studio.tour]*.* YOURDIR
In the rest of this Tour YOURDIR denotes the directory where the example resides (the original, $ISE_EIFFEL/examples/studio/tour , or a copy). Launching will use the operating system's mechanism for starting a program, so we look separately at Windows and at Unix/OpenVMS.
On Windows, you can launch EiffelStudio from the Start Menu by following the path:
Start --> Programs --> EiffelStudio Version --> EiffelStudio
where Version is the version number, e.g. 6.5. Alternatively, you can double-click the icon that the installation procedure will have added to your desktop (if you have selected that option during installation).
If this is the first time you are using EiffelStudio, you may get a dialog asking for an unlock code or inviting you to register the product. See your platform installation instructions for registration information.
To launch EiffelStudio on Unix or OpenVMS, change directory to YOURDIR and, from the command line, type
estudio
In general you can start EiffelStudio from any directory, but to make things simple for this Tour please make sure indeed to execute the estudio command from YOURDIR. (This will allow us to use relative rather than absolute names for some of the files involved.)
EiffelStudio first comes up with a window and a dialog on top of it; the dialog looks like this (from here on the look-and-feel will be slightly different on platforms other than Windows, but the content will be the same):
As this is our first project we want to "Add Project...". We could also
Create project", which would let you select one among the common schemes -- basic application, graphical Windows application, graphical multi-platform application, Microsoft .NET application -- and set up everything for you.
Open project", which would let you open a previously added project.
In future sessions you'll probably use "Create project" for a new project, as it takes care of generating a root class and configuration file for you, and Open project" to open an existing project.
Right now you first have to add the project, so click on the Add Project... button. This brings up a File Explorer inviting you to select an ECF file. The file you want is the file
simple.ecfin the directory "YOURDIR", (either $ISE_EIFFEL\examples\studio\tour or the copy that you have made). The ".ecf" file is an Eiffel Configuration File which contains the information necessary for construction of an Eiffel project.
So, use the File Explorer to find and select the file simple.ecf.
Click the button labeled Open to confirm. This starts compilation of your project.
During Eiffel compilation, you can observe the successive compilation steps, or "degrees", in the Outputs tool. The bulk of our little project is the EiffelBase library, which the EiffelStudio installation procedure has precompiled; as a result, there are only a few extra classes to compile, and the process is almost instantaneous on a state-of-the-art computer.
Note: As a frame of reference, on a Toshiba Satellite laptop, mobile dual core 1.73 GHz, 1 GB memory, running Windows Vista, this Eiffel compilation takes about 3.5 seconds.
After Eiffel compilation completes you will see the message
Eiffel Compilation Succeeded
At this stage your project has finished compiling.
So, congratulations! You have successfully compiled your first Eiffel project. More precisely your project has been "melted". Strange terminology, you may think; in a later section we'll see the derivation of the names used in the compilation process.
Our system doesn't do anything very exciting, but let's execute it anyway. Find and click the Run button (
) on the toolbar at the top of the EiffelStudio window.
This little application doesn't use graphics or any other fancy stuff. It simply creates some objects and displays some information. Output is accomplished by using the default Eiffel I/O features (from the EiffelBase classes ANY and STANDARD_FILES), and that output goes to a console. On Unix/Linux and OpenVMS it's the window from which you started EiffelStudio. On Windows, by default, it's a new console window that comes up when and if the system does its first output operation, and stays up you dismiss it:
The message "Press Return to finish the execution..." would not appear if you executed the system from outside of EiffelStudio, for example from a command line. Its purpose within EiffelStudio is clear: to let you see the console output; without it, the console would go away at the end of execution. (None of this applies to Unix/Linux/OpenVMS because no new console window was created when we executed the system.)
Before closing the console window, if you look at the main EiffelStudio window (by moving the console window aside) you will notice that it looks different than it did before. This is because EiffelStudio is now in debug mode, so it shows the fields useful in monitoring, controlled execution, and debugging. But we'll look at all this later. For the moment just dismiss the console by following the advice to "Press Return to finish the execution...": hit the Return or Enter key.
Before we proceed with the facilities of the environment, let's take a look at the way EiffelStudio organizes project files.
With EiffelStudio, you build projects. Most projects yield an executable system, although you can also build a project just to define a library for use by such systems.
Every session is relative to a project; you can start a new project from within EiffelStudio by following the menu path:
File --> New Project
Every project has a project directory which will contain the files generated and managed by EiffelStudio. The project directory may also host some of the source files containing your Eiffel classes, the ECF (eiffel configurationl file), and external software written in other languages. However, it is not required that everything be stored together; the source files and ecf may reside anywhere. Some users, in fact, like to put nothing other than the EiffelStudio-generated files in the project directory; this separates user-managed and system-managed files, and can facilitate configuration management, backups and porting.
In this simple Tour, things have been set up so that all the files of interest, source texts as well as generated ones, will appear in the project directory YOURDIR (either $ISE_EIFFEL\examples\studio\tour or the copy that you have made). Go to that project directory using the Windows explorer or a cd command, and look at its contents (using ls on Unix/Linux):
The contents of this YOURDIR directory includes the following:
.e , for "Eiffel": heir.e , invalid.e and others. These are the Eiffel source files, each containing one class. The recommended convention is to store a class of name CLASS_NAME into a file of name class_name.e , where class_name is the lower-case version of CLASS_NAME ; here, file heir.e contains the class HEIR and so on. As you may remember, Eiffel is case-insensitive, but the standard convention for class names is to write them in all upper case. Calling the file class_name.e is only a recommendation, not an obligation; but you are required to store one class per file. This keeps things simple and facilitates project and configuration management.
ecf extension. This is the configuration file that specifies this project. As you remember, the ECF file for this example was available as part of the delivery; we used it to compile the project. In most practical cases, however, you won't need to build an ECF; if you use the "Create project" option of EiffelStudio, EiffelStudio will build the ECF for you; if you change the Project Settings during a session, EiffelStudio will update the ECF. ECF files are written in a XML notation.
EIFGENs, for "EIFfel GENerations". EIFGENs is created and maintained by the compiler to store information about your project, including generated code for execution. EiffelStudio manages your project in such a way that EIFGENs can always be re-generated if need be; this means in particular that if things go wrong for any reason and you want to make a fresh start you can always delete this directory and recompile your system. This also means that you should not add any files into this directory, or modify any of its files, since a later compilation is free to change or regenerate whatever it chooses in EIFGENs.
simple.rc in the folder. This is a Windows resource file that was created automatically by EiffelStudio.
Later on, we will see that EiffelStudio may generate three more subdirectories of the project directory: Diagrams, if you produce graphical system diagrams; Documentation, if you request system documentation, for example HTML; and Metrics, if you perform measurements on your system. Other than these directories, EIFGENs EiffelStudio will not touch anything in the project directory, so you may safely add and change whatever files and subdirectories you like.
You seldom need to look into EIFGENs, although you should know that it's there. Right now if you check the contents of the project directory YOURDIR (using the Windows Explorer on Windows, the ls command on Unix, or some equivalent mechanism), you will see that EIFGENs has been created, itself with a subdirectory called classic which is the name of the target and which has some subdirectories, including W_Code which contains the generated code ( W for "Workbench" -- we'll see the reason later). Feel free to browse through it if you like, but don't change anything.
By the way, we are now done with any platform-specific instructions. Everything in the rest of this Tour, other than the graphical look-and-feel, will work the same across all EiffelStudio platforms.
It was important to take a look at how EiffelStudio stores your project, but unless your idea of fun is to poke around directories to look at compiler-generated files that's not really the exciting part yet. Among the most innovative aspects of EiffelStudio is a unique set of facilities to "browse" through a software system.
Contents
|
Browsing -- traversing the structure -- is particularly important in object-oriented development and especially in Eiffel because of the speed at which you can construct sophisticated class structures, making use of inheritance, genericity, the client relation and information hiding, and subjecting features to all kinds of adaptations -- renaming, redefinition, undefinition, effecting -- that are key to the expressive power of the software, but call for smart tools to keep track of what's going on. EiffelStudio's tools are second to none. Among their key properties:
Let's see how this works. First, take a look at the EiffelStudio window:
Note: If some parts are too small, just resize the window to arrive at something like what's on the figure. As soon as you have resized it, EiffelStudio will remember that size, and start up in the next session with the size you've set.
You can see that the bulk of the Development Window is divided into three primary panes or areas. The Editing tool is the large pane on the top left. The Editing tool supports a tabbed display of the elements in your system ... usually that's class text, and it's in the Editing tool that you make changes to your software. In the image above, it is targeted to the root cluster of our example system. We'll target the Editing tool to a class in a moment. The other two areas support multiple tools, also using a tabbed display. In the area below the Editing tool you see the Outputs tool currently selected. As you can see there are other tools represented by the tabs at the bottom of the same area. Likewise, the area to the right of the Editing tool shows the Groups tool selected, but in that area are also tabs for other tools. You will find that the layout of the Development Window is very flexible. Different tools can be made visible or hidden, panes can be removed, new panes created, tools can be docked in these areas or viewed as standalone windows. The appearance of EiffelStudio can be tailored to your needs and preferences.
So far we have talked about "the EiffelStudio window", but in fact that's not correct. What you see is one Development Window, of which you can have as many as you wish. Some people prefer to use a single development tool, avoiding screen clutter; others don't think twice about having lots of windows, taking the "desktop metaphor" to its full conclusion (some non-computer desktops are quite cluttered). There are many ways to start a new Development Window; for example if you look at the entries in the File menu at the top left -- don't select any of these entries yet, just look -- you'll see, among others, New window, which would create a new Development Window.
Whether you have one Development Window or many, each may have as its target an element of the system: system, cluster, class (the most common case), feature, run-time object. This simply means that the tool displays information about that element.
In our first look at the Development Window, the Editing tool was empty. To target it to a specific class, you can just type the class name -- if you know it -- into the Class field at the top left:
Let's use one of the most basic classes, STRING_32 from the Kernel Library of EiffelBase. Bring the cursor to the Class Field, click to make it active, type string_32 (or STRING_32 ) and the Enter key. As shown on the next figure, this causes a new tab to be created in the Editing tool and retargets the Development Window to class STRING_32. Note that you didn't have to worry about where the class resides in the files of your computer. Also, it doesn't matter, when you enter the name into the field, whether you use lower or upper case, or some mix; EiffelStudio will show the name in all upper case because that is the standard Eiffel convention for class names.
Retargeting by name is only one way to retarget a Development Window. There are other ways of retargeting that are useful at different times. Let's look at some of them.
Your first browsing action used a class of which you knew the name, STRING. What if you don't know what's in the system and want to explore it? Among other techniques, you can let the Groups tool, guide you through the classes that are available to your system.
An Eiffel system, as you know, is organized into clusters and libraries (and assemblies on some .NET systems). Additionally, clusters can be structured hierarchically into subclusters. You can expand the clusters and libraries nodes in the Groups tool (by clicking the little + signs to the left of the node icons) in order to see the classes. Try it, and what you see should look about like the following figure:
You'll see one cluster: root_cluster, containing the few classes specific to our Guided Tour system. Under libraries you'll see base which provides the classes of the EiffelBase library, and base_precompile which does not provide any classes directly (precompiles are present to speed up compilation time by precompiling classes, so base_precompile is just a precompiled version of the contents of the EiffelBase library). Let's go into base, Eiffel Software's open-source library of fundamental reusable mechanisms.
The most extensive subcluster of the EiffelBase library is structures, which contains implementations of major data structures and algorithms of computing science. Expand structures to see its own subclusters:
Note: If you initially don't see as many details as shown on this figure, you may get them by resizing the window, moving the vertical pane boundary, and/or scrolling.
The EiffelBase Data Structure library and its subclusters are described in the book Reusable Software. Let's go to one of the most frequently used subclusters, list, containing implementations of list structures. Expand the subcluster list. This time, since list is a terminal cluster, it's not subclusters you'll see, but classes, identified by small ellipses (
):
The ellipse, or "bubble", is indeed throughout EiffelStudio, as in the Business Object Notation (BON, the underlying graphical convention), the distinctive symbol for classes. You will notice that instead of the bubble, some classes are represented by what we call the "expanded" icon (
). These are still Eiffel classes. They are represented this way to show that they are marked as expanded. Still other classes have a modified bubble (
) indicating that they are marked as deferred.
Our second technique for retargeting a Development Window to a class (other than typing the class name as we did before) is to click the class in the Groups tool. Do this now: click LIST in the tree. It doesn't matter whether you click on the class name or the adjacent bubble. This retargets the tool to class LIST.
As the tool is now targeted to LIST, the Class Field at the top left now shows the name of that class, exactly as if we had typed that name, the way we did with STRING_32 in the previous method of retargeting.
Here now is a third way to retarget. Towards the top-left part of the Development Window there are Back and Forth buttons, which will enable you to revisit classes already seen during the current session:
Click the Back button. This retargets the tool to the class you visited previously: STRING_32. The Forth button, immediately to the right of Back, becomes active. Click it to retarget back to LIST.
Note that all buttons of the interface have a "tooltip" as shown in the figure above. if you move the cursor on a button, without clicking, and wait a second or so, a small message comes up, explaining the purpose of the button. Also, if there is an associated keyboard shortcut, it will be displayed in the tooltip.
As a fourth way to retarget -- there are more, and after this one we'll stop counting -- you can also use the Target History menu, which you can bring up through the little arrow to the right of the Class Field:
If you click this arrow -- the little black triangle -- you will see a menu of all your recent targets. Doing this now will only show the two classes visited so far, STRING_32 and LIST, but later on there will be more entries. By default EiffelStudio remembers 20 history entries; this is one of the settings you can change later if you wish, through the menu path:
Tools --> Preferences
If you find yourself often needing to examine a particular class, you can add it to your Favorites, much like adding an interesting page's web link to the bookmarks of a Web browser.
It's easy to add the current target -- currently, LIST -- to your Favorites. Do it now by following the menu path:
Favorites --> Add to Favorites
Now display the favorites; one way is to go back to that same Favorites menu:
Favorites --> Favorites
This gives us one more way to retarget a Development Window: click a class in the Favorites tool. Two ways actually, because once you add a class to Favorites, it appears in the Favorites menu and you can select it by choosing its menu item.
Right now we don't need the Favorites tool, so you can get rid of it by clicking the little Close icon at the top right of the Favorites pane:
After you close the Favorites tool, you may see some tool other than the Groups tool that we had been using. If this is the case, click on the Groups tool's tab at the bottom of the pane to make the library classes visible again.
So far, even though we've targeted to the Development Window to different classes, we've only used one Editor tab. But it is helpful sometimes to have views of several classes handy in multiple editor tabs. Its easy enough to create a new tab at the time that you target the Development Window to a new class. For example, you should see the class CHAIN in the Groups tool's view of the the list subcluster of structures (the same place we found class LIST. Instead of clicking on CHAIN the way we did LIST, this time control-right-click on CHAIN, that is to say, click with the rightmost button of the mouse while holding the CONTROL key on the keyboard. This creates a new tab for CHAIN and retargets the Development Window to that class, while sliding the existing tab for class LIST to the right a bit.
You can click on any of the tabs and the Development Window will be retargeted to the class associated with the tab. Each tab has a "Close" button on it, so you can close tabs you no longer need.
So, for now, close the tab with the class CHAIN and leave just the one tab with class LIST.
With all the techniques seen so far, you were able to retarget the current the Development Window to a new class. And that may be all you'll ever need. But, as noted earlier, you may also wish to have two or more Development Windows active simultaneously.
To create a new Development Window, follow the menu path:
File --> New Window
Empty development tool #1" because the window is (as yet) untargeted. You can also create a new Development Window by using the keyboard accelerator: CTRL-N.
You can close a Development Window either by clicking its close button in the corner of the window, or by following the menu path:
File --> Close Window
Be careful not to try to use:
File --> Exit
If, during a session, you end up with a number of windows active and want to see an active index to them, you can invoke the active windows tool by following the menu path:
View--> Tools--> Active windows
We haven't really looked at the text of a class yet. It's important anyway to see how EiffelStudio provides you with numerous, complementary views of your software. The Class tool and Feature tool are where the bulk of these views will be displayed, although the Editor tool does support some special views. For now we will concentrate on the views available in the Class tool.
Contents
|
We'll need just one development window for the moment, the one that was targeted to LIST. You should still have that window available from the previous Tour topic, and it should look about like this:
Note: If you don't see a development window targeted to LIST, just retarget one, as you know how to do this now, for example by typing the name followed by Enter in the Class Field at the top left.
First let's give ourselves more space. Right now we don't need the Groups tool or any of the other tools sharing that pane. We could get rid of them by clicking the close buttons on the top right corner of the panes. Then we could get them back later by following the menu path:
View --> Tools --> x
We do this by setting the pane containing the tools to Auto Hide. On the bar at the top of the pane, you'll see the Auto Hide icon (
) which looks like a pushpin.
Click the icon and you'll see the pane shrink into a set of tabs on the right window margin and the remaining panes will expand to fill the abandoned space. The tools in the pane will temporarily expand back out if you move your mouse cursor over their tabs. Try it with one. When you want the pane back in its original place permanently, you just expand one of the tabs by mousing over it, then click the Disable Auto Hide icon, which is the pushpin again, just horizontal this time.
Two panes remain, showing the Editor tool and the lower pane containing the Outputs tool and others. You can resize the panes by dragging the border between them. Make sure there's plenty of room in the lower pane.
Before we look at the Class tool, let's make sure that we set linked data share mode which will always display information about the current target. Go to the main menu bar and expand the menu item View. If you see a choice marked with the link context icon (
) and labeled Link Context Tool, then select it. After it has been selected, or if it has already been selected, then the label will read: Unlink Context Tool.
At the bottom of the lower pane you'll find a tab labeled Class. This gives you access to many forms of information about the current class -- the target of the development window. Click on the Class tab to bring up the Class tool. A set of buttons at the top enables you to display a number of views of the class. The currently highlighted button indicates the default view: Ancestors. You can see the others' names by moving your cursor over the various view icons, and reading the tooltips.
The view currently displayed, Ancestors, shows the inheritance structure that leads to the current target, LIST :
This shows that LIST is an heir of CHAIN which itself, as an example of multiple inheritance, is an heir of CURSOR_STRUCTURE, INDEXABLE, and -- twice, as an example of repeated inheritance -- SEQUENCE. If, because of direct or indirect repeated inheritance, a class appears more than once, the display doesn't repeat its ancestry the second and subsequent times; the omitted repetition appears as just three dots, ..., as illustrated here for the second occurrences of BAG, ACTIVE and others.
As you may have guessed, all the class names that appear on this display, by default in blue, can function as hyperlinks: you can use any one of them to retarget the Development Window to the corresponding class. This will be another major retargeting mechanism. But let's not pursue it for the moment and instead continue looking at the documentation views.
Next to Ancestors button is Descendants, which will give you the descendants of a class in a similar format:
The progeny of LIST, as you can see, is just as impressive as its ancestry.
Let's now look at the other formats, starting from the left. The first button, Clickable, gives the class text. It's essentially the same information as appears in the top Editing Tool (whose pane was reduced to its bare minimum in the last few pictures, showing only the first three lines or so), but with some differences:
Clickable view is just a view; you can't change it.
Clickable view is automatically formatted -- "pretty-printed" -- according to the standard Eiffel layout rules.
Clickable view does not include comments inside routine implementations ( do and once clauses), although it does retain features' header comments.
Clickable view uses colors and fonts to distinguish keywords, identifiers, comments and other syntactical elements. You can change the fonts and colors, like many other elements of the interface, through Tools --> Preferences. (Now is not the time.)
This view is called "Clickable" because, as we'll see later, every syntactical element on it is a hyperlink, which you can use for browsing.
After Clickable comes the Flat view button. The layout of the result is similar. The flat form of a class is the reconstructed class text including not only what's declared in the class itself but also everything that it inherits from its ancestors, direct or indirect. This applies to the flat form's features, which include ancestor features, but also to contracts: the flat form's invariant includes all clauses from ancestors' invariants, and the preconditions are expanded to take require else and ensure then clauses into consideration. (The Eiffel Tutorial explains these notions in detail.)
As a result, the Flat view shows the class text as it might have come out had inheritance (what a horrible thought even to contemplate!) not been available to write it.
The first two features appearing in the above display, cursor and first, are indeed inherited from ancestors, rather than declared in LIST itself. Note how EiffelStudio, when producing the flat form, adds a line of the form
-- (from CLASS_OF_ORIGIN)to the header comments of inherited routines, to document where they come from.
The flat form is an important notion of object technology, making it possible to understand a class by itself, regardless of the possibly rich inheritance structure that led to it. Looking at the Flat view of LIST, you may note how few of its properties come from the class itself; most of the interesting work has been done in ancestors, and LIST just adds a few details.
Note: If at any time you want to search for a certain pattern in the views displayed, you can type CTRL-F. A Find bar will come up at the bottom of the pane you are using. If you need more searching power, click the Search icon (
) in the development window's tool bar to invoke EiffelStudio's Search tool.
Next come two essential documentation views: Contract and Interface. Based on Eiffel's principles of Design by Contract, they document the interface properties of a class. Unlike the previous two, they do not show actual Eiffel texts, but information useful for client classes.
The contract form (also known as the short form of a class) is the class text deprived of any internal detail to retain interface information only. It discards any feature that's not exported (available to all clients); for the retained features, it discards the implementation -- do or once clause -- but retains the header (feature name, arguments, results), the header comment, and the contracts (precondition, postcondition, invariant) minus any contract clause that refers to a non-exported feature and hence would be useless to clients.
As you will know, particularly if you have read the book Object-Oriented Software Construction, 2nd Edition, the contract form is the preferred way of documenting software elements, especially reusable components, as it provides clients with just the right level of abstraction: precise enough thanks to the type signature and the contracts; clear enough thanks to the header comments; and general enough since it omits implementation details that are irrelevant to client programmers (and might lead them to write client code that won't work any more if the implementation changes).
In practice you will often want to use, instead of the Contract view, the next one, Interface, also known as "flat-short form" and "flat contract form", which applies the same rules to the flat form rather than to the original class. This means it shows information on all the features of the class, immediate (defined in the class itself) as well as inherited, whereas the short form, non-flat, only considers immediate features. The Interface view provides the complete interface information for the class. Try it now on class LIST.
The next two buttons are for the Ancestors and Descendants views, which we have already seen, showing classes connected with the target through one of the two inter-class relations, inheritance. After them come Clients and Suppliers, to list the classes connected through the other relation, client. Clicking the Clients button shows the list of clients of LIST.
Now click the next button to see the Suppliers of LIST.
The only two classes that LIST needs for its own algorithms are basic types from the Kernel Library, BOOLEAN and INTEGER_32. In Eiffel, as you may remember, all types are defined by classes, even those describing such elementary values as integers and booleans.
Let's resist the natural urge to go see now what the classes INTEGER_32 and BOOLEAN look like, and instead continue our survey of views. The remaining views will all display information about the features of the class. The first of them, Attributes, lists the attributes. It's not very interesting for LIST, a deferred class with only one attribute -- you can check this for yourself by clicking the Attributes button -- so let's look at the next one. Click the Routines button now to display information about the routines of class LIST :
The sections of this display group routines according to the ancestors of LIST -- including LIST itself -- that first introduced them; for example append originally comes from CHAIN and back from BILINEAR. Much of the benefit of this display comes from its support for browsing: all the colored elements, representing classes and features, will be "clickable" hyperlinks.
The Invariants button shows the complete class invariant for LIST. This includes all invariant clauses that have been inherited from all ancestors.
Other Class tool buttons display information in the same format as Attributes and Routines. Each selects a specific subset of the target class's features. You can now try any of the others by clicking the corresponding button:
Deferred features: abstract features which don't have an implementation in the current class, only in eventual descendants. Try this for LIST ; you'll see that this deferred class indeed has a number of deferred features.
Once and constants: constant attributes, "once functions" which provide shared objects (close to the "singleton" pattern), and once procedures which provide a convenient initialization mechanism. LIST has 'Operating_environment' and 'Io' inherited from the parent class ANY.
External features, implemented as calls to routines, macros or other elements implemented in other languages. LIST hasn't any.
Exported features: those available to all clients. LIST has quite a few.
Once you're done looking at the different views, let's undo the changes that we made to the configuration of the development window at the beginning of this section in Making some room.
Reduce the relative size of the lower pane.
Then go to one of the tabs on the right margin of the development window, Groups, will work. Hold your cursor over it for a moment and it should expand. Then click the Disable Auto Hide icon, the horizontal pushpin, to restore the rightmost pane.
Contents
|
We saw in Viewing Classes how EiffelStudio panes could be resized and how the Auto Hide feature works for a pane.
Now let's look at some other ways in which you can customize the layout the EiffelStudio tools.
EiffelStudio uses a default tools layout that generally reflects the preferences of a majority of users. So if you don't change anything in the way that the EiffelStudio interface is originally set up, you should still be able to work well enough. Also, be aware that as new versions of EiffelStudio emerge, it is possible that the layout that "generally reflects the preferences of a majority of users" may change. So, don't be too surprised if things look just a little different after installing a new version.
After considerable experience using EiffelStudio, you may decide that certain changes to the default make sense for the way that you work. For example, you may always want to have certain tools visible which were not visible by default. Once you make a change like this, EiffelStudio generally remembers that change and it will be in force the next time you open EiffelStudio. But you can also save a complete tools layout and recall it at a later time. For example, you might have two or three different development modes that you work in, and have a saved tools layout for each.
The ways in which the EiffelStudio tools can be arranged are nearly endless. You can make tools visible or hide them. You can make almost any tool a tab in almost any pane. You can re-order the tabs for a pane. You can pull tools completely out of EiffelStudio as free-floating windows. You can create additional panes as needed. Almost any pane can be "pinned" open or "auto hidden".
In view of this, it seems fitting that the first item that we should cover is how to revert back to the default layout in the case in which you get the tool layout in such a state that you just want dismiss the changes that you made and start over.
You can use the menu path:
View --> Tools Layout --> Reset Tools Layout
Figure 1
So at the end of the section Viewing Classes we manually reversed the changes that we had made to the layout to make additional space. We could have just selected Reset Tools Layout to restore the default layout.
You can try this now and see the effect. Your tools layout will probably not change very much.
You can see in the image above that you would also follow that menu path in order to save a tools layout or to activate one that you had previously saved.
At the right end of the top bar for each tool you will see buttons that help you control the way the tool and its containing pane are displayed. Here are the icons and what they mean:
There are a few subtleties you should understand when using these:
The pane in which the Editing tool resides is special. It is the only pane that supports minimize. And it does not support Auto Hide, nor Close. We'll learn a little more about this in the section on Docking.
When you maximize a pane it fills all available space. At the same time, its maximize icon changes to the Restore icon. When you click Restore, the pane relinquishes the extra space it annexed when you maximized it, and then returns to its original size and location.
The Close button will close only the current tool. So, that tool goes away, but any other tools in the same pane remain. However, when you close the last tool in a pane, the pane itself disappears and the space is absorbed by other panes. Remember that you can re-display closed tools through the menu path:
View --> Tools --> tool name
Note: EiffelStudio supports a number of key shortcuts (sometimes called accelerators, some of which can be useful for changing aspects of the Development Window. For example, CTRL+M will toggle the Editing pane between Maximize and Restore, and CTRL+N will create a fresh Development Window. Keyboard shortcuts themselves are tailorable in the EiffelStudio Preferences.
Within a particular pane, it is possible to have many tools visible. Each will be represented as a tab at the bottom of the pane. For example, the pane that contains the Class and Feature tools has the following tabs by default in the version that is current at the time of this writing:
Figure 2
One easy way to customize your tool layout is to change the order of these tabs if you prefer. Just drag a tab horizontally to a new position to the right or left of where it originally was located and release it. As you drag the tab, you'll see it relocate itself, so you'll know just were it will end up when you release it.
So suppose that you felt that it would be more convenient to your style of work to have the Outputs tool be the left most tool, versus the Class tool. Just drag it over there ... and now your tabs should reflect the new order:
Figure 3
Try this now, if you'd like but be careful to move the tab only horizontally along the row of other tabs. If you move it off the row of tabs, you may inadvertently enter the extraordinary, but more complex realm of docking, our next topic. Just in case you do get off the row of tabs and you see strange icons appearing on the Development Window, don't release the mouse button, just press the ESC key to cancel the dragging action.
The docking ability within EiffelStudio is arguably the most powerful tool at your disposal for tailoring the tools layout to your liking. Docking can be a little daunting at first, but once you understand a few concepts, you will likely find it both easy to use and helpful.
Maybe the first thing to know about docking is that EiffelStudio gives you the option of locking elements of the interface against inadvertent changes in docking. Following the menu path:
View --> Docking Lock
Perhaps the second thing to understand, if you haven't already guessed, is that, for docking purposes, the EiffelStudio interface supports toolbars and two different types of panes. One type of pane is the one in which the Editing tools reside, which we'll call an editing pane. The other is the type of pane is the tools pane where other tools can be docked.
So, with this in mind, we can take another look at the EiffelStudio layout.
Figure 4
Here we see the editing pane with one editing tool targeted to the class LIST.
There are two tools panes. Docked in one are the Class, Feature, Outputs, and Error List tools. In the other are the Groups, Features, and AutoTest tools ... and to the right of the AutoTest tab we see the icon (
) and a number indicating that there are more tabs, but no room to display them. In this case there is only one more tab; it is for the Favorites tool. Of course, if the that tools pane were a little wider, we would see the tab for the Favorites tool and the "continued" icon and the number would disappear.
It turns out that there are actually two more tools panes in this layout. One contains the Diagrams tool and the other contains the Dependency, Metrics, and Info tools. These two panes are Auto Hidden so we only see the minimum evidence that they exist ... just their tabs. You can tell that these are two different panes by how the tabs are distributed. Diagram is somewhat "off by itself" whereas Dependency, Metrics and Info are grouped closely together.
As we learned in Viewing Classes you can make one of these tool panes visible by moving your cursor over it, or clicking on one its tabs. The pane will expose itself for the length of time that the cursor remains over it, then recede into hiding again when the cursor is moved away.
Try this now with the Diagram tool. The pane housing the diagram tool appears from the bottom of the screen. Notice also that it has occluded the pane containing Class, Feature, Outputs, and Error List tools, and about half of the pane containing the Groups, Features, AutoTest, and Favorites tools.
Figure 5
So, Auto Hide works well to keep panes that we might not use very often out of the way ... but still pretty handy.
Let's dive into our first docking (or maybe undocking) experience. Suppose, though, that you were in the analysis and design phase of a project and you wanted the Diagram tool to be open and available at all times. Of course, you could move your cursor over it to "un-hide" it, then pin it open. But then it would be covering the other tool panes which we use often.
One great capability of the docking mechanisms in EiffelStudio is that you can disconnect, or float, a pane away from the rest of the EiffelStudio development window. Let's float the hidden pane that now contains just the Diagram tool out to the right of the entire Development Window.
In order to float this tool pane, we first have to set Auto Hide off.
Note: In versions of EiffelStudio starting with version 6.6, it will no longer be necessary to set Auto Hide off before moving a pane.
So move your cursor over the Diagram tab and the pane should expand (if it does not make it self visible, then click on the tab). Then move to the upper right and click the horizontal pushpin icon (
) to turn off Auto Hide and pin the pane open.
Figure 6
You may notice that a pane that is auto hidden may, when it expands, occlude other panes. However, when you turn of Auto Hide by pinning the pane open, any panes that it had occluded will become at least minimally visible. In the case of this example, the pane containing the Class tool was temporarily covered by the expanded Diagram pane, as was the row of tabs on the pane containing Groups. When you pin the Diagram pane open, the title bar for the pane with the Class tool becomes visible, and the pane with the Groups tool gets shortened to fit above the Diagram tool's pane.
It is at this point that new EiffelStudio sometimes have problems understanding what's happening. So read the following description of what's going on before you actually try to move the pane ... and don't forget that you can always reset the tools layout if things don't go the way you intended.
Now that we've turned off Auto Hide for Diagram's pane, we can move the pane and either re-dock it somewhere else in the development window or, as is our intention, "float" it as a window separate from the Development Window.
To undock and re-dock or float a pane, you drag the pane by its title bar (but don't do this quite yet). As soon as you begin to drag the pane, you will see the look of the Development window change:
Figure 7
In the figure you can see the cursor arrow on the title bar of the pane. The pane has been dragged very slightly and EiffelStudio has sensed that we want to move the pane from its current position. In response, EiffelStudio has overlaid the Development Window with a set of icons that represent valid docking targets for the pane being moved. We'll look closer at those in a moment.
But for now, notice the large dark, semi-transparent docking feedback area at the bottom left of the image above. This represents what will happen to your pane if you release the mouse button at the current time. So in the case of the figure above, releasing the mouse button immediately will float the pane on top of the Development Window. This is nearly our intent, although we want to move the floating pane out to the right of the Development Window. So, without releasing we drag the pane off the top and to the right of the Development Window, then release it.
Figure 8
So go ahead and try it now. If you've pinned the pane with the Diagram tool open, then drag the pane by its title bar out to the right and off the Development Window and release it.
The problem that some users have when first trying to adjust the tool layout using docking (without the benefit of this Guided Tour) is that once they move a pane, it's not obvious to them what to do next to get the effect that they want. As a consequence, they attempt to put things back the way that they were when they first dragged the pane ... and usually they aren't successful. Remember that you can always press the ESC key to cancel the drag while still holding the mouse button down.
Now let's take a look at the target graphics and what they mean, and we'll do an exercise in which we put the pane with the Diagram tool back where it was originally.
In Figure 7 above, you can see the docking target graphics. You see this figure:
Figure 9
in two places, and four smaller figures:
Figure 10
one near each border of the Development Window.
The graphic in Figure 9, shaped like a "plus" sign or cross, will appear in any pane which is a valid docking target for the pane you are moving. So, in Figure 7, those panes are the pane housing the Groups tool and the one housing the Class tool.
The center of the graphic represents the target pane itself. So, if you drag your pane over the center of the graphic and release it, your pane will now become a new tab in the target pane. You can see the docking feedback area hinting to this effect. In the figure below, the pane with the Diagram tool was dragged over the center of the target graphic on the tool with the Class pane. Notice that the whole pane is covered with the docking feedback area, which even shows the hint of a new tab.
Figure 11
If we were to release the pane at this point, it would dock as a new tab along side Class, Feature, Outputs, and Error List. In this case, the pane we are moving contains only one tool, Diagram, but if it contained multiple tools, each of those tools would become a new tab in the target pane.
But remember that our goal in this exercise is to restore the pane holding the Diagram tool back to its original position. So, making it a tab in the pane with Class, won't achieve that goal. Let's look at some other possibilities.
What happens if we drag our pane over one of the tips of the cross shaped target graphic? These targets will allow us to split the target pane into two panes, one containing the original content and the other containing the content of the pane we are moving. The original pane will be split according to which tip of the cross you drop your pane onto. For example dropping on the right tip will split the target pane into left and right panes an put your pane on the right. Again you can see this depicted in a preview when you hover over one of these, as shown below.
Figure 12
It's pretty obvious that this will not get Diagram back to its original location. The only options left unexplained are the four graphics shown in Figure 10. These each look like a detached version of one of the tips of the cross shaped graphic, but they are located along the four edges of the Development Window. If you drop your pane on one of these it will add it as a new pane along the corresponding margin of the Development Window.
We know that originally our pane with Diagram was in Auto Hide mode at the bottom of the Development Window.
So, drag the pane from its floating position and drop it at the bottom of the Development window on this graphic:
The effect is that now your pane has been docked back into the Development Window at the bottom. The only thing left to do now is turn Auto Hide back on by clicking the push-pin icon. Now the pane that houses the Diagram tool is back in its original place in the layout.
As we learned earlier in Minimizing, maximizing, restoring, and closing tools, the pane in which the Editing tools reside has special properties and restrictions not present for panes housing other tools. It's the same for docking. Just as you can't close the Editing pane, you can't re-dock it in any other location. You can't dock other tools, the Feature tool for example, in the Editing pane (notice that you don't get a targeting cross in the Editing pane when you drag a pane).
Although the Editing pane can house only Editing tools, you can re-order the tabs for Editing tools and you can re-dock Editing tools by splitting the Editing pane. For example you might want to look at two classes side by side in two different panes. In the image below, after opening tabs for classes LIST and CHAIN, we dragged the tab for CHAIN and dropped over the right tip of the cross shaped graphic that appeared in the Editing pane. Then we put the pane Groups and the one with Class in Auto Hide to enlarge the size of the Editing tools. This allows us to view LIST and CHAIN side by side.
Figure 13
You can drag toolbars and re-dock them in different places. You can float toolbars in the same way you would do a tool pane. In the figure below, the Project toolbar has been dragged away from its default home to the right of the Standard Buttons toolbar. Now it's over undockable space, so if released here it will float, just as we saw with tool panes.
Figure 14
When you move a toolbar, drag it by its "head". The head is indicated by an icon (
) that looks like a vertical row of dots at the left end of each toolbar.
The figure above shows that there are two "rows" available for placing toolbars. This is the way it is in the default layout. But the number of rows can be expanded if needed. So, if you drag a toolbar toward the bottom of the toolbar area, you will see that a new row will become available in which you can dock the toolbar that you are moving.
Figure 15
In the figure above, the Project toolbar has been dragged near the bottom of the toolbar area, and a new toolbar row has opened up to allow the Project toolbar to be docked there.
In addition to using the docking facilities to move toolbars around to suit your work style, you can also customize each toolbar by adding, removing, or re-ordering the buttons on that toolbar. See more about this on the page Toolbar customization.
Software development is, most of the time, cooperative work. You must tell the rest of the team what you're up to, and find out what they can offer you. Bring in distributed development -- increasingly common these days, with some people working at headquarters, others at home, others traveling, an offshore team half a world away ... -- and the problem becomes even more critical.
EiffelStudio provides unique facilities to make such distributed development possible in a safe, effective, harmonious way. Some of the key criteria are:
EiffelStudio's documentation generation satisfies all these requirements.
Contents
|
Let's see how documentation works by starting to generate it for our Guided Tour system -- which really means for EiffelBase, since that's what it mostly consists of. The HTML result is available as part of the present documentation (we'll tell you where in just a minute), so you don't have to regenerate it unless you want to. Indeed we'll show you when to click Cancel if you are happy with the pre-generated version. But let's get started anyway to understand the principles and possibilities.
Click the following menu entry, used to generate documentation:
Project --> Generate documentation...
This is the next-to-last entry in the Project menu. The last one, by the way, XMI Export ..., is directly relevant too: it will make it possible to export information in the standard XML representation for UML, for consumption by third-party products such as Rational Rose. But for the moment we choose the Documentation entry to start the Eiffel Documentation Wizard.
The Wizard starts with a list of available output formats, also called filters:
The filter names correspond to major documentation formats which EiffelStudio supports by default. Among the most important, listed here in rough order of appearance in the list:
ASCII : plain text, no formatting codes.
eiffel : essentially the same as ASCII; useful if you want EiffelStudio to pretty-print your class texts and replace the originals, as explained below.
MML : internal format for Adobe FrameMaker.
Postscript : to generate Adobe Postscript output, suitable for printing on a Postscript printer, display on a Postscript previewer such as Ghostscript, or distilling to Adobe PDF.
COM : to generate class specifications in the form of an Interface Description Language (IDL) interface for Microsoft's COM component model.
RTF : Microsoft's Rich Text Format, used in particular for Windows "Help" files.
TeX1, TeX2 : two variants for Donald Knuth's TEX processing format.
troff : if you already know what this is, congratulations (or condolences), you've been around the industry for a while. This is a traditional text-processing format available on Unix systems. Also works for the gtroff variant.
html-classic : HTML, no style sheets. The next variant, with style sheets, is strongly recommended unless your colleagues will be reading your documentation with Mosaic 1, vintage 1993, or Netscape 2, Vintage 1995.
html-stylesheet : HTML with style sheets. This is particularly attractive for Web publishing not only because the output makes full use of style sheet capabilities (fonts, colors, layout, formatting) but also because it becomes trivial to change the look-and-feel to support any style you or your users like, even after generation, simply by editing the style sheet file.
Not only do these predefined filters provide support for a number of important industry formats; better yet, if you want another format not represented on the list, or would like to adapt an existing format to your own style preferences, it's easy to define a new filter. The list that EiffelStudio displays comes from the files with a .fil extension that it finds in a subdirectory of the installation:
$ISE_EIFFEL/studio/filters
To define a new filter, simply add a file to this directory. Filters are expressed in a simple notation called EFF ( Eiffel Filter Format ), general enough to support a wide variety of tools for text processing, project management, Web publishing etc. The best way to define a new filter is usually to start from an existing one and adapt it. You will find the specification of EFF at the end of this manual, here .
Let's select the most obviously attractive of the predefined filters: HTML with stylesheets. Click the line html-stylesheet in the list to make it active, then click Next at the bottom of the Documentation Wizard window. The next window appears:
In this pane you select which parts of your system you want to be included in the documentation. By default, all library and cluster names are checked. You should uncheck any that you do not want included.
Note that each library or cluster name must be checked or unchecked individually. For example, unchecking "base" will not automatically deselect "elks" and "ise" which appear under "base".
For this Tour we'll want to generate everything, including EiffelBase, so make sure that in the end all library and cluster names are checked, as in the figure. Then click Next.
The next step of the documentation wizard asks you to select Note entries:
Eiffel classes, as you know, may start with an note entry that enables class authors to include documentary information in any category they like. It is standard (and part of the official style guidelines) to include at the very least an entry of the form description: Descriptive text in every class. The earlier displays of class LIST showed that entry, which read " Sequential lists, without commitment to a particular representation".
You may have noted that the purpose of Eiffel's note clauses is, conceptually, similar to that of metatags in HTML. Metatags carry information which Web page visitors do not normally see in the browser; this information is available, however, to search engines and other tools that explore and classify Web pages. So it seems quite appropriate to generate metatags from note entries.
The dialog illustrated in the last figure lets you select the entries you wish to transform into metatags. It appears only if you have selected an HTML filter. It lists all the note tags found anywhere in the system; those that are checked will be retained for metatags. Initially unchecked are three tags ("date", "revision", and "status") conventionally used -- at Eiffel Software and other Eiffel sites -- for interfacing with configuration management tools, and hence of internal interest only.
There is no need to change the default selection, so just click Next.
The next step of the Documentation Wizard lets you specify what kinds of documents you want to generate:
This is a very important facility since it gives you control over how much you want to publish about the properties of the software:
The dialog shown on the last figure lets you specify the exact combination you wish. The figure indicates the default options.
This time, if we generate anything, we'll generate everything. Please check all the boxes (the generation won't occur until the last step) and click Next to move to the next dialog of the Documentation Wizard.
The next dialog only appears when you have asked to generate diagrams:
Although we didn't use this possibility yet, the Diagram view lets you define different subviews of any cluster. One view might show inheritance only, the other client links only; one might include all classes, the other hide some library classes. The last dialog shown will allow you, for any cluster, to select a subview other than the default for the generated diagram.
Here we only have the default view, so just click Next.
The last dialog simply asks you where you want to generate the result:
By default, as shown, EiffelStudio will produce the documentation in a subdirectory -- created for the occasion, if it doesn't exist yet -- of the project directory:
.../your_project_directory/Documentation
You may, however, select any other location you like. In the case of HTML generation, as here, EiffelStudio takes great care to use only relative hyperlinks so that you can move the Documentation directory around, for use either on a file system or on your Web site, with the guarantee that the hyperlinks will work -- as long as you move the entire directory together.
To continue the Guided Tour, you do not need to complete the generation now unless you want to. If you are happy to continue without generating the documentation at the moment then click Cancel on the last dialog.
Note: If you do prefer to produce your own local version of the full documentation for the guided tour system, click "Finish". The process takes 7 minutes on the Thinkpad configuration mentioned earlier, and generates a documentation directory of about 220 megabytes.
Let's take a look at the generated documentation. We start with the root of the generated documentation, Documentation/index.html :
This root page shows overall information about the system. The top set of links, repeated at the bottom, enables you to browse the system from its list of classes, its list of clusters, or the cluster hierarchy; note the box labeled to Go, which provides a built-in search engine, enabling you to type any class list and go directly to the corresponding page. Let's look at the class list: click the box Classes at the top left.
This shows the beginning of the list of classes, alphabetically sorted. You could click any class to get the corresponding information, but wait; we'll look at individual classes in a moment. Instead, click Cluster hierarchy to see the overall organization of the system into clusters:
Click BASE to see details of the EiffelBase library where (under EiffelStudio) we had found the class LIST used as example in the preceding sections:
This indicates the relations of the cluster to others in the hierarchy, and its list of classes. Again you could click any class name but instead note the link (diagram) next to the cluster name near the top. Remember that when generating the documentation we elected to generate everything, diagrams included. Hadn't we checked the corresponding check box, the (diagram) link wouldn't be there. Click it now to get the diagram that has been generated for BASE:
The output is a diagram showing graphically the classes of the cluster and their inheritance relations. All EiffelStudio-generated HTML diagrams use the PNG graphics format ( Portable Network Graphics ), supported by all recent browsers.
The class bubbles in a diagram are all hyperlinks. To see the HTML documentation for our old friend the class LIST you could just click its bubble. But because this diagram includes the whole library and is automatically generated, you'd have to look around a bit for the LIST bubble. Go ahead and do that if you wish, or just type the class name LIST into the Go to field and press return:
The display shows key information on the class, in a form called the "Chart format" listing the ancestors and then the features, divided into Queries (shown in part on the figure) and Commands. Note that all class names and feature names are hyperlinks, which would lead you to the appropriate place in a class text.
The top row of hyperlinks now includes class formats corresponding to those we discovered in Viewing Classes in EiffelStudio: Relations (covering ancestors, descendants, clients, suppliers, ), full Text, Contracts, Flat contracts. Click Flat contracts to see the full interface of the class:
We'll stop this brief review here but you may continue browsing through the HTML pages if you like. Note how closely the appearance of the class texts, flat forms, contract forms, diagrams and other forms of documentation matches the corresponding formats under EiffelStudio.
Although we suggest staying with the standard, you can easily change any convention that doesn't match your own preferences:
Tools --> Preferences.
default.css. You will find this file in the generated documentation directory; alternatively, to ensure the changes are applicable to the generated documentation of all future projects, edit defaults.css in the directory after backing it up. For more profound changes in the structure of the generated HTML, you may also backup and edit the Eiffel Filter Format file html-stylesheet.fil in the same directory. EFF is described in the Appendix .
$ISE_EIFFEL/studio/filters
The documentation generation mechanisms, using HTML or other formats, let you publish your designs, at the level of detail you desire, on an Intranet, the Internet, or as part of documents you release. They are an important part of the power of EiffelStudio for quality software development.
Let us get back to EiffelStudio. Before studying the documentation generation we saw how to display properties of classes. It's also interesting to explore the properties of features.
There are two tools with similar sounding names that we will use to explore features:
Your Development Window should still be targeted to class LIST, from the last view, Routines, that you displayed on it. If you've lost it, just retarget a Development Window to this class.
Let's start by making the Features tool visible. To see the Features tool click on the tab labeled
(note that this is the plural "Features" versus the singular "Feature").
If the tab for the Features tool is not visible, bring it back by following the menu path:
View --> Tools --> Features
While we are at it, let's get make the Feature tool visible as well. Click on the tab on the lower pane that's labeled
. As with the Features tool, if the Feature tab is missing, you can use the menu path to restore it.
One more thing, and we'll look at some features. If you restarted EiffelStudio since you worked through the Viewing Classes section, you may have to select Link Context Tool again from the View menu.
Contents
|
The list of features, organized by feature clauses, appears in the Features tool:
The class only has a few immediate features because most of its interesting features are inherited. Make sure the Editor tool is tall enough (as on the above figure) and click the feature forth, the last one, in the Feature Tree on the left. This makes the feature the Editor tool's current target, and scrolls the text to its declaration:
Note how both of the top target fields are now filled: the first one shows the target class, LIST, and the second one shows the target feature, forth.
Now let's look at the views of the feature forth provided in the Feature tool.
A view of forth is already visible in the Feature tool. By default, it is the Flat view.
The flat view of a feature, similar in concept to the flat view of a class, gives the full text of a feature, taking into account any inherited precondition or postcondition clauses. Here the feature as declared in the class appears in the top Editing Tool, with no precondition and an ensure then postcondition clause. But it's a redefinition of an inherited feature; the flat view in the bottom Context Tool shows the full precondition, inherited from the ancestor LINEAR, as well as the postcondition from LIST.
Flat is just one of the available Feature Views, shown by the buttons on the toolbar of the Feature tool.
You can mouse-over the different buttons to see the views they represent.
Just to the left of Flat, Basic Text gives the feature text, fully clickable.
To the right of Flat is Callers. Try it now by clicking the corresponding button. You may have to scroll down some in the display to see the series of entries show in the image below;
This view shows all the places in the system that call the routine, or one of its redefinitions. Such information can be invaluable for debugging in particular. The successive paragraphs correspond to the various versions of forth in class LIST, its ancestors and its descendants. Reading from the top we'll examine a few entries:
LIST is called in LIST itself by the function is_equal.
LIST is called in routines in two debugger classes RT_DBG_CALL_RECORD and RT_DBG_COMMON
forth from MULTI_ARRAY_LIST is a version in a descendant of LIST, and is called by three routines of MULTI_ARRAY_LIST itself: duplicate, put_right, and remove_right.
forth has been renamed and that renamed version is called. For example child_forth from LINKED_TREE is descendant version of forth and is called by routines in LINKED_CURSOR_TREE and LINKED_TREE.
The following five view buttons are similar except that they let you specify what kind of callers you are looking for, or what is being called by the currently selected feature. Feel free to explore these views.
After the caller/callee views, the next view button is Implementers.
This is a very useful view, showing all the ancestors and descendants of LIST that provide a separate version of forth, including the original introduction of this feature in LINEAR and subsequent redeclarations (redefinitions or effectings). The mention (version from) signals the version applicable to the current class, here LIST.
Since all class and feature names on these views are hyperlinks, you can display any of the listed versions in a new Development Window by control-right-clicking it (we will see shortly how to display it in the same tool). Right-click on the feature name forth on the line that reads MULTI_ARRAY_LIST forth. This brings up a context menu and chose Show --> Text. The tool is now targeted to the routine forth from MULTI_ARRAY_LIST, so that you can see the implementation of the routine in that class.
We still have two unexplored views, Ancestor versions and Descendant versions. Click the first of these to obtain the ancestor versions of forth from MULTI_ARRAY_LIST.
The format is self-explanatory: for each ancestor of MULTI_ARRAY_LIST that has a version of MULTI_ARRAY_LIST 's forth feature, it indicates the name of that feature -- which could be something else than forth as a result of renaming, although here this happens only in descendants, not ancestors -- and the version of the feature applicable to the given class.
In the case of feature merging (combining several features inherited from different parents, in conformance with the rules of the language) there could be more than one history branch, in this case each branch is labeled Branch #X.
The next button, Descendant versions, similarly tells you all that happens to a feature in the descendants of the current class.
The last button, Homonyms, displays all the features of the system which, related or not to the current feature by redeclaration, have the same name. You can then explore any such feature to see if the relationship is more than casual.
In any system or library that takes advantage of inheritance and its associated mechanisms -- renaming, redefinition, effecting, undefinition, multiple and repeated inheritance, polymorphism, dynamic binding -- the feature browsing facilities that we have just explored are invaluable to track what happens to features. What makes them even more precious is their connection with the rest of the browsing and documentation capabilities, especially the pick-and-drop which we will now study.
You now know quite a few ways of re-targeting a Development Window to a "development object" -- a class or a feature -- but haven't yet seen one of the most important: "Pick-and-Drop", which lets you pick a development object that you have spotted anywhere in the display, and retarget the current tool, or another, to it.
Contents
|
We restart from the last state, with a Development Window target to feature forth of class LIST. The next figure shows the whole window; it should look like what you see as a result of the last operations. We'll use the Descendant versions view of the Feature Tab.
If for some reason the window doesn't look like the next figure, it's easy to reconstruct it: make sure both the Cluster tree and the Feature tree are visible (if not, make visible using the instructions given in Viewing Classes); target the tool to class LIST; target further to its feature forth by clicking that feature name in the Features tool's roll of the features of LIST; make sure both the top-left Editing tool and the bottom-left Feature tool are visible; in the Feature tool, select the Descendant versions format.
In the Feature tool near the bottom, there is an entry that reads
MULTI_ARRAY_LIST [G] forth
referring to the version of feature forth in class MULTI_ARRAY_LIST. Let's assume you want to see what that version actually is. It suffices to retarget the tool to it. Of course you could type or copy-paste the class name MULTI_ARRAY_LIST in the Class field at the top of the window, and the feature name forth in the adjacent Feature field. But there is an easier way; after all, you have just seen a reference to the feature, through its name as it appears in the Descendant version format, so it's natural to use it directly from the graphical interface.
As we've seen before, you could control-right-click on the feature name at the place where it appears; this would create a new tab and retarget the Development Window to forth from MULTI_ARRAY_LIST. But you might not necessarily want a new tab. Instead you can use Pick-and-Drop to retarget the current window.
Here is how it works. Position the cursor on the desired feature reference: the word forth in the line forth MULTI_ARRAY_LIST. Right-click, that is to say click the rightmost mouse button and then release it. You will see a context menu that looks like the figure below.
The item we want to choose from this menu is "Pick Feature 'forth'". So do that now, by left-clicking over the item.
Now move the mouse around some, but without pressing any button:
The cursor has changed into a new shape, a cross representing the type of development object that you have picked, a feature. For a class, as you may have guessed, it would be a small ellipse ("bubble"). Each kind of development object that you may create and manipulate during your work with EiffelStudio has its distinctive icon. When you pick an item, you'll notice that the item's icon stays connected to its origin by a dotted line that stretches or shrinks as you move the icon around.
So, now you have picked the feature forth. You can drop it at any appropriate place to retarget the corresponding tool. Move your cursor (and the feature icon for forth) over the Editing tool now.
To drop, just right-click again. (That is to say, as before, press the rightmost mouse button and release it immediately.) Drop the icon representing {MULTI_ARRAY_LIST}.forth in the Editing tool.
This retargets the Development Window to the chosen feature, forth from the class MULTI_ARRAY_LIST. The Feature tool (assuming the Link Context tool option is selected), keeps its current view ( Descendant versions in the Feature tool) and now shows descendants of {MULTI_ARRAY_LIST}.forth.
In the example above, when you right-clicked over an item, you were presented with a "context" menu, containing choices applicable for the item you clicked. We chose to pick the item. It's possible that if you use pick-and-drop quite a bit that you might rather not see the context menu each time you right click. You can make this happen in a couple of ways. First, if you use the context menu most of the time, but you want to pick directly at other times, you can shift-right-click to bypass the context menu and pick the item immediately.
The other option is used if you want a right-click to pick by default, and only use the context menu occasionally. To make this happen, you need to change the Pick and drop (pnd) mode EiffelStudio preference. You can change this preference by following the menu path:
Tools --> Preferences...
With Pick and drop (pnd) mode set to True, you will always get a pick when you right-click over an development object. If you occasionally wish to use the context menu, then you would shift-right-click, which would cause the context menu to appear.
The Pick-and-Drop mechanism is very simple. It consists of three steps:
During the Move step, you can at any time cancel the whole operation simply through a left-click.
The Move step is actually optional: if the current position is a valid drop target, as explained next, you can drop immediately after the pick without moving the mouse.
The Pick-and-Drop mechanism relies on the metaphor of pebbles and holes. When you pick a development object, the cursor changes into a pebble whose shape represents the type of the development object: cluster, class, feature, run-time object ... You may then drop it into a hole, which can be a window, a tree view entry, or a hole-shaped icon. This performs the appropriate action such as retargeting a tool.
In the same way that Eiffel is a typed object-oriented language, the Pick-and-Drop mechanism is typed: you can only drop a pebble into a compatible hole. For example you may drop a class pebble into a Development Window, to retarget it to the chosen class. If you have picked a development object and have moved its pebble over an area which is an unacceptable place to drop it, you will notice that the pebble takes on its "disabled" form. An enabled class pebble (
), for example, would become a disabled class pebble (
) for the time that it's hovering over unfriendly territory.
In Eiffel, type compatibility is not necessarily type identity, but is governed by conformance, based on inheritance and polymorphism: to an entity of type POLYGON, you may assign not only an expression of that same type, but also one of type RECTANGLE, if class RECTANGLE inherits from -- conforms to -- class POLYGON. Similarly, EiffelStudio considers that the development type "feature" conforms to "class"; this means you may drop a feature into a Development Window targeted to a class; this will retarget the tool to the feature's class and the feature itself, with the text of the class scrolled to the position of the feature.
A good deal of the power of Pick-and-Drop comes from its connection with the various views of the Class and Feature tools ... and the Diagram tool which we will see later. As was mentioned when we saw these views, all the feature and class names or other graphical representations that appear in these views are clickable ; this means that you can select any of them as the source of a Pick-and-Drop.
As a result, you can quickly traverse a system and get to its essential properties by displaying the information of a class in any of the many available views -- the contract and flat contract of a class, its routines, its attributes, its clients, its ancestors, the ancestor and descendant versions of a feature, and so on -- then wherever you see a feature or class name follow the corresponding link. This proximity-based form of browsing, combined with the other techniques seen earlier, provides considerable help when you are dealing with a large, possibly complex system, and want to master its intricacies, be it for development, testing, debugging, maintenance or revision.
Other places where you can pick development objects include the icons representing classes and features in the Groups tool, Feature tool, and Favorites tool.
An important property of the pick-and-drop mechanism, shared by its cousin the right-click mechanism, has already been mentioned in this chapter: semantic consistency, which guarantees that the operations you can perform on a class, such as pick-and-drop, only depend on the development object to which you are applying the operation. It doesn't matter where you picked the object -- in any development tool under any view -- and in what form: textual, as a class or feature name; graphical representation, as a class bubble in the Diagram tool; or an icon, for example in the Groups tool, Features tool, Favorites tool.
The pebble that you see during the Move step of Pick-and-Drop represents the underlying development object -- such as a class or a feature -- regardless of how you got to it.
Pick-and-Drop works differently from the usual Drag-and-Drop present on many computing platforms. The usual Drag-and-Drop retains a role within EiffelStudio (to move class bubbles around in the Diagram view) and you may of course have to use it for operating system functions such as copying files. But the key EiffelStudio operation is Pick-and-Drop. This technique is motivated by careful consideration of ergonomics and user comfort. In particular:
If you are new to EiffelStudio you may find Pick-and-Drop surprising at first. We trust you will join the ranks of EiffelStudio users who consistently rate it among the most convenient features of the environment.
When you start repeatedly retargeting the Class and Feature tools -- especially when set to "unlinked" behavior -- you will notice the following properties:
Ancestors for the Class tool and Flat for the Feature tool -- is default view for the corresponding tool.
You know by now that if you pick an object and drop in into the Editing tool it will retarget the Development Window and will evict the previous occupant of the current Editing tool tab and display the dropped object in that tab. But, you can also use Pick-and-Drop to create new tabs in the Editing tool. Instead of dropping into a tab, drop the pebble instead in the tab bar of the Editing tool next to existing tabs, or on the "New Tab" icon (
) in the Standard buttons toolbar.
As a conclusion to this review of Pick-and-Drop let's recapitulate the various ways we've seen for retargeting a whole Development Window or a tool to a class:
| How to retarget | Same window/tab/tool, or new? | Where described |
| Type class name, then Enter, in class field at top-left of tool | Same | "Retargeting by name" in the chapter "Starting To Browse". |
| Choose class in Cluster tree | Same | "Retargeting from the Groups tool" in the chapter "Starting To Browse". |
| Choose class in Favorites | Same | "Adding to Favorites" in the chapter "Starting To Browse". |
| "Back" button | Same | "Moving back and forth" in the chapter "Starting To Browse". |
| "Forth" button | Same | "Moving back and forth" in the chapter "Starting To Browse". |
| Pick class from history list | Same | "The Target History" in the chapter "Starting To Browse". |
| Pick-and-drop | Existing or new (depending upon drop target) | Chapter "Retargeting Through Pick-and-Drop". |
| Control-right-click on class name or graphical representation found in any tool | New tab | "Starting a new tool" in the chapter "Starting To Browse". |
So far we have relied on existing class texts. Fascinating as it may be to explore excellent software such as EiffelBase, you probably want to write your own too (with the help of the reusable components in the Eiffel libraries). EiffelStudio provides a built-in editor -- as well as the ability to use some other editor if you prefer -- and sophisticated compilation mechanisms.
Contents
|
When we started, we compiled the example system. Let's recompile it, just to see. We'll see compilation entries in the Project menu, but the easiest for the moment is to use the compilation button (
) in the Project toolbar. Click this button. You haven't changed anything in the project since it was compiled (at least you were not supposed to!), so EiffelStudio will very quickly detect this and finish compilation. On our test platform this takes less than a second. Now of course we should see what happens if you do change something.
We don't want to touch EiffelBase classes (and in fact can't, since it is used in precompiled form), so let's focus on classes of our small root cluster. In the Groups tool, expand cluster root_cluster and click class PARENT to retarget the Development Window to it.
Make sure that the Editing Tool is big enough to display the text of the class:
The Editing Tool hosts a text editor which you can use to change the class text. Here the routine display starts by outputting a simple message; let's precede it by another line of display to check that we affected the outcome. We'll want to add the following two lines just after the do, before the first two instructions of the routine:
io.put_string ("THIS IS SOME ADDED TEXT") io.new_line
You can just use copy-paste from the example above: select the two lines with the mouse, copy them using CTRL-C (or Copy from the Edit menu), then paste them just after the do using CTRL-V (or Paste from the Edit menu). Add or remove tabs to align with the rest of the routine, so that the result will look like what's shown on the next figure. Please check the result and be careful not to introduce any mistakes; in the next section we'll study how EiffelStudio will report syntax and other errors, but right now we want to see what happens when everything is right!
Now save your changes; you may indifferently use CTRL-S, the Save entry from the Edit menu, or the Save button (
), at the cursor location on the figure. (If you forget to save, the next compilation will tell you so, and ask you if from now on you want all non-saved class edits to be saved automatically.)
Next compile again, using the Compilation button. Some "degree" messages appear quickly; EiffelStudio has found out what class has changed and deduced what exactly to recompile -- only a subset of the whole system. So this again will proceed very quickly.
Execute the system again now, using one of the execution buttons, with or without breakpoints, on the right in the bottom Project toolbar. You will see that the message output by the execution has changed to include the added string.
In studying the Class tool we discovered a number of views of a class text. For convenience, you can also display a number of these views in the Editing Tool, although only the basic Text view is editable. A row of buttons next to the Class and Feature fields lets you choose between them.
You can try some of these view now, although there is nothing exciting to show about class PARENT. Make sure to come back to the Text view -- through the leftmost of these buttons -- so that we can continue exploring the editing facilities.
The editing facilities in the Editing Tool are provided by the EiffelStudio Editor, a specialized tool supporting the development and update of Eiffel texts. As we'll see next, if you have a preferred editor you can use it instead, but the EiffelStudio Editor is worth knowing.
The EiffelStudio Reference section on the Editor provides many more details about editing functions. Here are the essentials.
First, the key property of any interactive system: Undo. You can cancel the latest editing command, or any earlier one performed during the current session, by choosing Undo from the Edit menu, or typing CTRL-Z. To cancel more than one command, apply Undo repetitively; there is no limit to the number of undoable commands within a session. (When you exit EiffelStudio, however, the editing history is lost.) To redo an undone command, use Redo from the Edit menu or CTRL-Y.
Note: Since right now we don't need to do any actual editing to continue this Guided Tour, we suggest that you don't change the text of class PARENT but simply look up the menu entries described next, without actually selecting them. If you do make a change, voluntary or not, you should at the end of this editor discussion perform enough Undo commands to get the text of class PARENT back to its original state.
To copy, cut and paste use the corresponding entries in the Edit menu or the familiar keyboard shortcuts CTRL-C, CTRL-X and CTRL-V.
When you edit text, it will be automatically indented according to standard Eiffel style rules. If you prefer to remain in charge of your own indenting, you can disable this facility through
Tools --> Preferences --> Editor
To indent a sequence of lines, select the lines, then use <codeang=text> Edit --> Advanced --> Indent selection</code> You can also use the Tab key, but only if the selection consists of one or more entire lines; otherwise typing Tab will simply replace the selected text with a Tab character. Shift-Tab will similarly decrease indentation by one step.
To comment out a sequence of lines, select them and use
Edit --> Advanced --> Comment
CTRL-K. Conversely, CTRL-Shift-K will uncomment. Also in the Edit --> Advanced menu are "set to upper case", with the keyboard shortcut CTRL-U, and to lower case, CTRL-Shift-U.
Other useful facilities of the Edit --> Advanced menu are:
Embed in "if", or CTRL-I, which will create a conditional instruction and include the selected instructions in it.
Embed in "debug", CTRL-D, which will include the selected instructions in a debug ... end instruction, so that their execution becomes conditional on a Debug compilation option.
The editor lets you search for text and replace occurrences, individually or globally. We assume you have seen a text search facility before, so we'll just emphasize some of the less obvious features.
To start a search, make sure the Search Tool is active by clicking the Search button in the top toolbar (this one we'll let you find) or using the
Edit --> Find
Note: If you press CTRL-F in a tool you will get a quick search bar that quickly allows you to search for something in the current text.
The Search Tool presents a number of self-explanatory options:
You can enter a term to replace your search term in the Replace with box.
Having filled the two fields, you can elect to replace the last found occurrence, or all occurrences at once.
The Search for field has an associated drop-down list, so that you can reuse a recently entered search string without retyping it.
Particularly interesting are the editor's automatic completion facilities (often, we shorten the name to auto-completion). Well, particularly interesting for most people: maybe you like your editor to do the grunt work for you, or maybe you don't. In the latter case -- if you prefer to be in control of all the details -- don't worry: through
Tools --> Preferences --> Editor
The EiffelStudio Editor knows about Eiffel syntax and will recognize syntactic elements as you type them. It will color them according to standard conventions: basic elements in black, keywords in blue, comments in dark red. You can change these conventions through Preferences.
If you start typing a control structure through its opening keyword, such as if, or from for a loop, the editor will automatically display the structure of the whole construct. Here for example is the result if you type the from followed by Return/Enter at the beginning of our example routine:
This has produced the structure of an Eiffel loop: from ... until ... loop ... end. You can then fill in the blanks with the appropriate expression and instructions. The generated lines start with the appropriate number of Tab characters to support the standard Eiffel indenting conventions. If you want a more compact style, follow the from with a space rather than Return. Typing if followed by Return or a space will similarly produce the outline of a conditional instruction.
Also interesting is feature completion. Feature completion is activated by default, and it works at two levels:
CTRL-SPACE to get possible completions.
In both cases, if more than one completion is possible, you will get a menu of the possibilities. You can scroll through it with the up and down arrow keys, or the mouse, and select one through Enter or double-click. You can also or give up through the Escape key.
Here for example is the menu you will see in the body of our example routine if you type io. , where io is the feature, coming from class ANY, that provides access to standard input and output facilities:
If only one completion is possible, no menu appears; the completion is selected.
When a menu of possible completions is displayed, you can use the arrow keys to traverse the list.
If you select a routine with arguments, auto-complete will show the arguments and their types, allowing you to provide your value for each argument. The figure below shows auto-completion of a routine with only one argument.
You can see that the argument is pre-selected and is of type STRING_8. As soon as you begin to type your substitution for the argument, the pre-selected argument definition is replaced with what you type. When you complete an argument, the Tab key will either pre-select the next argument (in the case of routines with multiple arguments), or place the cursor to the right of the right parenthesis that terminates the routine call (in the case of the last argument).
Auto-completion will only work for queries that were present at the time of the last successful compilation. So if you add an attribute, say attr, to the current class, and do not recompile, typing a then CTRL-SPACE will not display attr. To make sure that it's included in completion proposals, save and recompile. (Remember, incremental compilation is fast in EiffelStudio, so there is nothing wrong in compiling early and often.) The same rule holds for features of other classes, those that will appear in proposed completions after a period.
The features proposed for auto-completion include all features of the class: those declared in the class itself, or immediate features, and those inherited from proper ancestors, direct or indirect, with one exception: by default the list will not include features from the universal class ANY, which serves as ancestor to all classes and provides many features for comparison, copying, input-output, reflection etc. Including ANY's features would clutter all menus with too many features. So for example typing i followed by CTRL-SPACE will not suggest io among the possible completions. You can change this policy through Preferences. The policy does not apply to remote feature completion for an entity x declared of type ANY. In the case that you type x., auto-completion will produce the list of ANY's features.
You may have a favorite editor and prefer to use it, at least in some cases. The EiffelStudio incremental compilation mechanism, to be studied shortly, recognizes that files have been modified outside of EiffelStudio (by checking their time stamps) and will without any fuss take their modified versions into account.
You can also call an outside editor on a class from within EiffelStudio. Just use
File --> External editor
This will call the editor of your choice. The default is Notepad on Windows and Vi on Unix and Linux. You can easily change this to any editor by entering the desired editor command in
Tools --> Preferences --> General --> External editor command
In this command text you can use the two special notations $target and $line ; when EiffelStudio calls the selected command, it will replace any occurrence of $target by the name of the file where the current class resides, and $line by the line number at which the Editing Tool is currently scrolled. If you include one or both of these markers at the appropriate argument positions for the command, this will enable you -- assuming the editor supports the appropriate options -- to make sure it starts at exactly the right place. For example the default editor command under Unix is
vi +$line $targetmeaning: start the Vi editor on the $target file, initially positioned at line $line (the + line_number command-line option of Vi directs it to start at line line_number ).
If you start an external editor on a class, then exit the editor after possibly making changes, EiffelStudio will immediately update the class text in the Editing Tool. More generally, note that EiffelStudio will detect changes made separately on the same class, and warn you of possible conflicts.
Several important text editors from various providers have Eiffel modes, which support the syntax-directed editing of Eiffel texts. They include:
So far we have tried to make sure that everything went smoothly. But in actual software development you may encounter error situations, and it is useful to know what can happen then.
Let's remind ourselves first of how the language is specified. The ISO/ECMA Eiffel standard and the book Eiffel: The Language carefully distinguish between three levels of description: syntax, validity and semantics. Their roles are clearly distinct:
Writable entity, continues with the symbol :=, and ends with an Expression. This is a purely structural specification, saying nothing for example about the types of the Writable and the Expression.
Expression must conform -- a property of its type, defined rigorously on the basis of inheritance -- to the left-hand-side Writable. Eiffel has about 75 validity rules; part of the language's originality is that these rules are of the "if and only if" form, not only telling you individual error cases ("this is valid only if ... ") but also reassuring you that your text will in fact be valid if it satisfies the conditions listed exhaustively.
Writable by the value of the right-hand-side Expression at the time the assignment is executed, with precise rules on the different possible cases involving references, objects and simple values.
You may make an error at any of these levels:
= instead of := for the assignment symbol is a syntax error.
your_integer := your_real, with the types suggested by the names, is a validity error.
Syntax and validity errors will be detected by the compilation process. For semantic errors, you will rely on contract checking and on the debugging tools described later. Let's look now at examples of the first two cases.
To see what happens for a syntax error, replace the keyword do by dont in the routine display of class PARENT (click the position immediately after the o and type nt.). Save the file by clicking the Save button or using CTRL-S and then compile the system.
The error shows up in the Error List tool. You can expand the entry to show the point at which the error was recognized by the compiler.
To correct the error, just bring the mouse back to its location, remove the spurious nt, and click Save again; also click Compile to make sure that the project is recompiled up-to-date.
You may wonder why the syntax error messages are not a little more verbose than just Syntax error. The reason is merely that Eiffel's syntax, being simple and regular, does not require sophisticated error messages; syntax errors usually result from trivial oversights. If you make a syntax error and the reason is not immediately clear, check the syntax summary in the Quick reference to the Eiffel programming language or the ISO/ECMA Eiffel Standard.
A validity error is a violation of one of the validity constraints given in ISO/ECMA Eiffel Standard. Every such constraint is identified by a four-letter code of the form VXXX (the first letter is always V).
A validity error will produce a precise error message, which includes the validity code. Although short, the error message is usually sufficient to find out what the error is. If not, you can get the complete rule, straight from the book.
To see this mechanism at work, let us introduce a validity error. There is in fact one ready for you in class TESTROOT. Target a Development Window to this class; at the end of its text, just before the final end, you will find the following comment line:
-- inv: INVALID;If uncommented, this is a declaration of a feature of type INVALID. A class called INVALID indeed exists in file invalid.e of the root cluster, but it contains a validity error. To see what it is, remove the initial double-hyphen -- in the above line from class TESTROOT so that it is not a comment any more.
Click Save, then Compile. Compilation starts but after a few degrees it stops with an error message that appears in the Error List tool. Expand the entry and perhaps do some resizing to see it in its entirety:
As the error message indicates, you have (shame on you) violated the validity rule VUAR, which requires the number and types of actual arguments in a routine call to match the number and types of formal arguments declared in the routine.
One of the interesting properties of the error message is that everything in color is clickable: class name, feature name, but also the error code. This means that you can start a Pick-and-Drop on any of these elements to find out more.
For example, to see the exact context of the error, pick-and-drop the name of the affected feature, display -- appearing in green on the fifth non-blank line -- and pick-and-drop it to the Editing tool. This displays the erroneous feature:
Note on this display a special property of Pick-and-Drop when its source is a feature name appearing in a validity error message: the instruction that causes the error is highlighted.
In the error message in the Error List tool, the error code itself, VUAR, is also clickable. Assuming the message was not sufficient to understand the error, you can use it to start a Pick-and-Drop. Do this now, by picking that code and starting to move the mouse, but not dropping yet. The pebble shape for such information elements is a question mark ? enclosed in a small gold talk bubble (
). Like other picked objects, when it is not over a droppable target, the pebble will be crossed in red (
). The place to drop is the Explanation hole (
) in the Error List toolbar:
When you drop the pebble, you'll see the Compilation Error Wizard appear:
The wizard displays the complete text of the violated rule. Depending upon the particular violation, the rule will come straight from the pages of either Eiffel: The Language or the ISO/ECMA Eiffel standard. In this case, the VUAR rule definition used comes from Chapter 22, page 369 of Eiffel: The Language. An rule cited from the ISO/ECMA Eiffel standard will be state as such and will include the specific edition of the standard and the section number, for example:
VEVI, ECMA-367, 2nd edition, section 8.19.17
The VUAR rule that we violated has two clauses, numbered. Since the error message showed the error code as VUAR(1), the violated clause is the first; this convention of showing the clause number in parentheses applies to all multi-clause validity constraints.
To correct the error the easiest is to go back to class TESTROOT and reinstate the comment symbol -- (two consecutive hyphens) on the erroneous line. Save and compile to continue with a valid system.
The next set of EiffelStudio capabilities enables you to control and monitor the execution of your systems. The obvious immediate application is to debugging; but the more general goal is to let you follow the execution of your systems, explore the object structures, and gain a better understanding of the software.
Contents
|
Before looking at debugging facilities don't forget that debugging in Eiffel is different. The presence of Design by Contract mechanisms gives the debugging process a clear sense of direction. The speed of the recompilation process makes it easy to recompile after a change; after getting rid of syntax and validity errors, you run the system again, and remaining errors are often caught as violations of contract clauses -- routine preconditions, routine postconditions, class invariants.
The facilities to be described now are also useful when you find such an error, as they will help you study its execution context. In fact, one of the characteristics of the debugging mechanism is that there is no "debugger" proper, no more than there is a "browser"; you have instead a set of facilities supporting controlled execution and debugging. This means for example that:
To control the execution you will set breakpoints, indicating places where you want to interrupt the execution. You may set a breakpoint on an individual instruction of a routine, on the routine's precondition or postcondition, or on the routine as a whole, meaning its first operation (precondition or instruction).
A group of icons on the Project Toolbar help control breakpoints. They are known in EiffelStudio terminology as "buttonholes", meaning that they can serve both as buttons (you can click them to get some functions) and holes (you can pick-and-drop into them to get some other functions).
The labels correspond to the icons' use as buttons: enable all set breakpoints (
), disable them all (
), remove them all (
), and display information on current breakpoints using the Breakpoints tool (
). The difference between "disabling" and "removing" is that disabling turns off breakpoints until further notice but remembers them, so that you can later re-enable them, whereas "removing" clears them for good.
Here you also see icons for controlling execution: run (
), step-by-step (
), step into routine (
), step out of routine (
).
Target a Development Window to the class TESTROOT and pick-and-drop the name of the procedure make (the first routine, after the declaration of the two attributes o1 and o2) to the Enable all icon, used here as a hole. This sets and enables a breakpoint on the routine. Click the button labeled Show information about breakpoints (
). This will invoke the Breakpoints tool, as shown in the next figure.
This shows that so far you have enabled only one breakpoint. For a finer degree of control, let's look at the feature's flat form. Close the Breakpoints tool, then pick-and-drop make from the Editing Tool to the Feature tool (anywhere in the lower left pane should do; this sets the pane's context to the Feature Tool. Select the Flat view if that wasn't the last one used:
The small circles on the left side of the Flat form indicate breakpoint positions. Empty ones are not set; enabled breakpoints are marked by a circle filled with red. At the moment only one is enabled, corresponding to the first instruction of the routine since, as noted, setting a breakpoint on a routine as a whole means setting it on its first operation.
By (left) clicking on a breakpoint mark, you toggle it between enabled and not set. You can also right-click on a mark to get a menu of possibilities:
Try enabling and unsetting a few of these marks; you might get something like this:
The breakpoint mark for the routine's third instruction, create o2, is filled but not red (
); this means it is set but not enabled. You can obtain this by right-clicking on the mark and choosing Disable breakpoint on the menu that comes up. Any potential breakpoint will be in one of three states: not set (
); set and enabled (
); set but not enabled (
).
Remember, you can see the complete list of enabled and disabled breakpoints by making the Breakpoints tool visible ... which you do by clicking the Show information about breakpoints (
) button in the Project Toolbar.
For the remainder of this chapter it doesn't matter which exact breakpoints of make you've set, as long as the one on its first instruction is set and enabled (red-filled circle) as above. Please make sure this is the case before proceeding.
To execute, you will use the following Run buttons in the Project toolbar, or the corresponding entries in the Execution menu:
Most of the buttons shown here are enabled, but at different times some of them will be disabled (grayed out.)
The Execution menu entries will also remind you of shortcuts: F10 for Step-by-step, F11 for Step into routine, Shift-F11 for Step out of routine, CTRL-F5 for Run ignoring breakpoints, F5 for Run with breakpoints, CTRL-Shift-F5 for Interrupt execution, Shift-F5 for Stop execution.
Start execution of the compiled system by clicking the Run button (
). Run actually means "Run and stop at enabled breakpoints." EiffelStudio automatically switches to Execution mode to accommodate supplementary tools providing debugging information. Execution stops on the breakpoint that you have enabled on the first instruction of procedure make:
By default, in Execution mode, EiffelStudio looks a little different. Specifically, the Feature tool now occupies the space that was previously held by the Editing tool. The Call Stack is in the tall pane on the right, and the Object tool and Watch tool are on the bottom, under the Feature tool.
The Call Stack indicates that execution has stopped in make. The Feature tool shows the flat form of that routine, with an icon (
) to indicate the stop point which execution has reached. The Object tool, which shows the content of current object and (later) related objects. At the moment you can see that:
TESTROOT.
o1 and o2, both declared as type PARENT, for which the corresponding fields in the current object are both void; this is as expected since you haven't yet executed the two creation instructions create {HEIR} o1 and create o2, as they come after the breakpoint.
io has not yet been called, but after it has it will return an object of type STD_FILES.
The execution-time objects that you may display in the Object tool are our latest kind of EiffelStudio "development object", along with classes, features, explanations, clusters; notice the distinctive icon (
), a rectangular mesh shape suggestive of an object's division into fields. It appears colored for actual objects and gray (
) for Void references such as operating_environment.
Click twice on Step-by-step (
), or press the function key F10 twice. Monitor, in the flat form of make, the marker that shows execution progress; note that the marker always points to the next operation to be executed. After the two steps, the Feature and Object tools look like this:
The last instruction that you executed is create {HEIR} o1, meaning create an object and attach it to o1, but instead of using the declared type PARENT of o1 use its proper descendant HEIR. As a result, the entry for o1 in the Object tool no longer shows Void but an object of type HEIR. Note that all objects are identified by their addresses in hexadecimal; such an address is by itself meaningless, but enables you to see quickly whether two object references are attached to the same object. The addresses you see as you run the Guided Tour will -- except for some unlikely coincidence -- be different from the ones appearing here.
Note that since the garbage collector compacts memory and hence may move objects around, the address of a given object is not guaranteed to remain the same throughout a session.
To see the details of the object, expand its entry in the Object tool.
Now notice what happens if you pick the type name (HEIR) from the entry for object o1 in the Object tool, and then drop it in the Feature tool above. The context changes from the Feature tool to the Class tool and is retargeted on HEIR. The Class tool has switched to the default format for classes, Ancestors, and is showing the ancestors of HEIR. Click the Feature tab to get back to feature information for the continuation of our debugging session.
Click Step-by-step once more to advance just before the call o1.display.
Choosing Step-by-step again would execute the next step in the current routine, the call o1.display, treating the entire execution of display from class HEIR as a single operation. Assume instead that you want to go into that routine and follow the details of its execution. For one thing, you might not know that it's a routine of class HEIR, since o1 is declared of type PARENT and it's only through polymorphism, that is, o1 being dynamically of type HEIR at this point, and through dynamic binding, that the execution ends up calling a routine from HEIR. Of course here it's obvious because of the wording of the create a few lines up, but in many cases, especially all those for which polymorphism and dynamic binding are really interesting, the exact type won't be immediately clear from the neighboring software text.
Click the Step into routine button (or press F11). This brings execution to the beginning of the appropriate display routine in class HEIR.
While you're here notice the Call Stack tool. It shows that we are currently executing feature display of class HEIR, which, as can be seen on the second line of the stack, was called from feature make of class TESTROOT.
Now click Step out of routine (
), or press Shift-F11 to finish the execution of display. This brings you back to the next instruction of the calling routine, make of TESTROOT.
You may now click the Stop execution button (
), or press Shift-F5, to end execution. The execution-specific tools go away and the display returns to what it was before execution.
In this little application nothing runs long enough to give you the time to interrupt it. In a longer-running application you may want to interrupt execution, without necessarily terminating it, while it's running (not stopped on a breakpoint). This is the purpose of the Interrupt execution button (
), which can also be triggered by pressing CTRL-Shift-F5. It will interrupt execution at the closest potential breakpoint position, letting you -- as when execution stops because of an exception -- take advantage of all the debugging and browsing facilities to see what's going on inside your running system. You may then restart execution -- with or without breakpoints, single-stepping, out of the current routine, into the next routine -- by choosing the appropriate Run button
In debugging sessions for more advanced applications, you will also find self-explanatory mechanisms enabling you, in addition to what we have seen, to examine all the objects on the "call stack": arguments and local entities of the current routine, its caller, caller's caller and so on.
The combination of these facilities provides you with a level of dynamic information on the execution of your system that matches the static information that the browsing mechanisms studied in preceding sections provide about the system's structure.
Note: The following few pages contain the AutoTest tutorial. This tutorial uses a different software example than the bulk of the EiffelStudio Guided Tour. If this is your first time through, you may want to delay the AutoTest tutorial until you have completed the rest of the Guided Tour, then come back to it when you're feeling more familiar with EiffelStudio.
Note: To users of V6.6 and later: As of V6.6, the New Eiffel test wizard panes have changed somewhat from this documentation. V6.6 introduces the ability to store certain preferred values for creating tests. The advantage is that one need not enter this information on wizard panes each time a test is created. Because preferred values can be stored, the panes containing the values more likely to change between test creations are presented earlier than other panes. In previous versions, these panes were presented later, as shown in this documentation. The documentation will be updated in the future to reflect the newer wizard sequences and pane layouts.
AutoTest is a tool that helps you to create, manage, and run tests against your software. AutoTest is accessible directly as a part of EiffelStudio, but works to a large extent behind the scenes so that it doesn't get in the way of your development activities. In other words, even though you may be accumulating a substantial collection of test software along with your project software, you can still run and deliver your project software without going to a lot of trouble to separate the two. Tests managed by AutoTest stay handy and can be run any time to help make sure everything always stands up to the scrutiny of testing.
This tutorial will guide you through the use of AutoTest. A reference section for AutoTest is also available.
Recommended: At least on your first viewing of this tutorial, take the sections in the order in which they are presented. There are three different types of tests supported by AutoTest. Each type of test is discussed on its own page. But to avoid repetition, the pages for the second and third types of tests omit some of the detail in the first and assume a familiarity with the example.
Caution:
1) At this time, AutoTest will work only for project targets in the classic Eiffel environment. This means that projects targeted to Microsoft .NET will not be able to use AutoTest.
2) Currently, the use of AutoTest should be restricted to projects built without void-safe settings.
Recommended: During the transition to void-safe Eiffel, projects can be built using experimental mode. This mode is as stable as non-experimental mode, but includes some facilities that might break existing code in a few circumstances. However, since version 6.5, EiffelStudio itself is built in experimental mode, so we recommend that you use AutoTest only on projects also built using experimental mode. Experimental mode can be invoked by using the "-experiment" option from the command line, or on Microsoft Windows by following the Start menu path to EiffelStudio and selecting experimental mode. As of version 6.6, the mode that was experimental in previous versions, becomes the default mode.
See Also:
AutoTest reference
Contents
|
Developers test software in the hope that the testing process will expose faults in the software they've developed. Most developers also realize that no amount of testing will ever prove software to be bug free. So while testing is a virtuous activity that we dare not neglect, we are wise to temper our expectation of the practical value of testing.
A test is designed to exercise a software element given certain inputs and execution state. The state is observed after the test execution to see if the software element has behaved in a manner that is consistent with its specification.
As a body of software is developed and tested, a large number of tests may accumulate. This large suite of tests can be run at any time in order to ensure that a change or the addition of a new software element does not cause a previously successful test now to fail. Some software development processes call for running a whole suite of tests after every increment of development activity. This type of testing is often referred to as regression testing, because it tends to expose software which had been satisfying its tests at one time, but because of some development activity has regressed to a failing state.
Creating, managing and running a large number of tests manually can be time-consuming, messy, and error-prone, thus the motivation for automated testing tools. Testing tools help programmers to create, maintain, and execute a suite of tests by automating the activity. During the last few years, both testing methods and tools have become more sophisticated.
Some of today's development methods require tests to be written before the software elements they test. Then the tests are included as a part of the software specification. But tests can only reflect a very small subset of the possible execution cases. Testing can never replace a comprehensive software specification.
The great advantage you have with Eiffel, of course, is that the specification for a software element exists in its contract. Like the tests mentioned above, contracts for software are written prior to implementation. So, importantly, tests are not a part of a software specification in Eiffel.
With contract checking enabled at run time, the running software's behavior is constantly monitored against the contract's expectations. In other words, for routines, the precondition defines an acceptable state in which the routine can execute, and the postcondition defines an acceptable state after successful execution. The class invariant defines the constraints necessary for instances of a class to be valid.
A term commonly used in software testing is "oracle". Tests are generally looked at as having two parts, the first part is a mechanism that exercises (runs or calls) a particular software element in a given context. The second part is the "oracle" whose responsibility it is to determine whether the software element passes or fails the test. Not surprisingly, test oracles in other testing frameworks often look a lot like assertions in Eiffel. So the advantage for Eiffel is that the test oracles for all routines are already written as the postconditions on routines and class invariants.
The presence of preconditions provides another advantage. Preconditions make it possible to automate testing in ways unavailable in other environments. Because of preconditions, we already have information about the limits of valid inputs to routines. So it's possible to generate a call to a routine we want to test automatically and with a context that meets the routine's precondition.
AutoTest attempts to capitalize on the testing advantages inherent in Eiffel due to Design by Contract. AutoTest consists of an interactive interface, and a library of classes which support testing activity.
The testing support classes are distributed with EiffelStudio and exist in the testing subfolder of the libraries folder. With the exception of one class which we will discuss soon, the classes in "testing" are not intended to be used directly by developers. They exist to support the functionality of AutoTest.
The interface for AutoTest is accessible through the EiffelStudio development environment. You may find it already resident as a tab in the right hand pane next to Clusters, Features, and Favorites. If it's not there, then you can bring it up by following the menu path:
View --> Tools --> Testing Tool
The AutoTest interface helps you to create and execute tests on the software you develop. The interface contains a wizard called the New Eiffel Test Wizard which helps you create or generate the types of tests you need. We'll learn more about the interface and the wizard as we go along. But first, let's look at what constitutes a test. For AutoTest, we define the term test in the context of some other testing terminology:
Definition -- Test class: An effective class that inherits from the class EQA_TEST_SET.
Definition -- Test: Any procedure of a test class that satisfies all of the following conditions:
1) Is exported to ANY
2) Is immediate (i.e., introduced within the text of the test class)
3) Takes no arguments
Definition -- Test set: The set of tests in a test class.
Definition -- Test suite: A set of test classes (and by implication the tests contained therein) which is designed to test some particular software system or library.
Whenever you use AutoTest, it will find your test classes, those classes that inherit from EQA_TEST_SET. When you run tests, it will execute all the tests in those classes, or a subset of tests that you choose. So, you have probably figured out that the one class from the testing library that you may need to know a little about is EQA_TEST_SET. But you don't have to know very much, because AutoTest can help you construct your test classes.
There are three different types of tests supported by AutoTest:
Each test of any of these types ultimately is a feature of class that inherits from EQA_TEST_SET. Ordinarily, though, the three types of tests won't be mixed in a test class. That is, any one particular test class will contain only one type of test. But from the point of view of AutoTest, all types of tests are managed and run the same way. We will discuss these types of tests in more detail later, but for right now, let's just establish some definitions.
Definition -- Manual test: A test manually coded within a test class.
Manual tests are features, procedures in fact, of classes that inherit from EQA_TEST_SET. In many simple cases, test classes containing manual tests inherit directly from EQA_TEST_SET, but that's not a requirement. Occasionally it can be useful for test classes to inherit from a descendant of EQA_TEST_SET that provides additional functionality.
A manual test is "manual" in the sense that you code the essential procedural part of the test by hand. But you really don't have to deal with the more mundane business of creating the whole test class and ensuring the proper inheritance. The New Eiffel Test Wizard helps out by automatically creating the shell of a test class and the shell of a test for you to fill in. Then it's pretty easy to add new tests manually to an existing test class.
Definition -- Extracted test: A test that has been created during the execution of a system as a result of a developer request or a failure of the system. Extracted with the test is the current runtime state. When run, the test will attempt to recreate the runtime context.
Extracted tests are convenient because they allow you to accumulate tests that are based on actual failures of your software (good for the software, not so good for your ego!). Once these tests are in your suite of tests, they are available from then on.
Definition -- Generated test: A test that is the product of generating and running a series of randomly generated invocations of target routines.
The process of creating generated tests is sometimes known in the community as creating via AutoTest. The randomly generated calls to target routines which were created and run are discarded at the completion of the creation. But from the results of these calls, a set of permanent tests is distilled. These are the generated tests.
Generated tests are made possible by Design by Contract. Hopefully, you remember that one thing that DbC gives us is the handy ability to assign blame when something goes wrong. When a test makes a call to a routine we want to test, if a contract violation occurs, it may be the fault of the called routine or it may be the fault of the caller ... and that depends upon what type of contract violation has occurred. The contract violations that are interesting to AutoTest in the process of synthesizing tests are only those in which the called routine is at fault. That is, postcondition and invariant violations. AutoTest will then create a generated test for every unique failure in which the called routine being tested was to blame.
Here are two more definitions:
Definition -- Target routine: A routine that is to be tested by a test. Sometimes called a "routine under test."
Definition -- Target class: A class that contains target routines. Sometimes called a "class under test."
In its simplest form, a test is a routine that issues a call to some routine you've developed in some class you've developed.
So the tests and the test classes are in the realm of testing and are used to test the target routines in target classes which are the real product of your software development project.
AutoTest will manage and run the tests in any test class whether or not they actually test any target routines. Even though the test shown below doesn't test anything, it still qualifies as a test. Naturally, it would seem silly to keep a test around that doesn't test anything, but the important thing to understand is that AutoTest will work with anything that matches the definitions of test and test class above. That is, once tests are created, AutoTest doesn't really have a stake in what you are trying to test.
note description: "[ Eiffel tests that can be executed by testing tool. ]" author: "EiffelStudio test wizard" date: "$Date$" revision: "$Revision$" testing: "type/manual" class MY_TEST_CLASS inherit EQA_TEST_SET feature -- Test routines my_test -- New test routine do assert ("not_implemented", False) end end
This test class was created by AutoTest's New Eiffel Test Wizard. It is about as simple a test class as there can be. Its only value is to illustrate the basic form of AutoTest tests. So, let's look at that form.
It is clear that MY_TEST_CLASS is an effective class that inherits from EQA_TEST_SET, so that makes it fit the definition of a test class. And, it's also clear the my_test is a feature of MY_TEST_CLASS, specifically a procedure, exported to ANY, requiring no arguments. That qualifies my_test as a test. If MY_TEST_CLASS is located in a test cluster of your project, then AutoTest will find it and be able to run it whenever you request.
This test would always fail because of the assert that the wizard put in the implementation. So if you asked AutoTest to run your tests, it would tell you that my_test was a failed test, for the reason: "not_implemented". The assert is not a necessary part of a test. The wizard puts it there to remind you that the test has not been implemented. If you removed the assert line from the test, then the test would always succeed, which would be nice, but it would be succeeding at testing nothing! We'll see more later about what it means for tests to succeed and fail.
But first let's get some exposure to the AutoTest interface, by building a manual test for a routine in a simple class.
Contents
|
For developing our manual test, let's use a simple system that contains a class modeling bank accounts. Here are two classes that will make up our system. The first, APPLICATION will be the root class of our system. APPLICATION really only serves to declare an attribute of type BANK_ACCOUNT, which is the class we will write a test against. APPLICATION looks like this:
And here's the class BANK_ACCOUNT:
class BANK_ACCOUNT inherit ANY redefine default_create end feature default_create do balance := 0 end balance: INTEGER deposit (an_amount: INTEGER) -- Deposit `an_amount'. require amount_large_enough: an_amount > 0 do ensure balance_increased: balance > old balance deposited: balance = old balance + an_amount end withdraw (an_amount: INTEGER) -- Withdraw `an_amount'. require amount_large_enough: an_amount > 0 amount_valid: balance >= an_amount do balance := balance - an_amount ensure balance_decreased: balance < old balance withdrawn: balance = old balance + an_amount end invariant balance_not_negative: balance >= 0 end
You shouldn't let it worry you if you've noticed that the class BANK_ACCOUNT contains some flaws. We'll deal with these later.
If you want to work along with this tutorial, you should be able to copy the text of each these classes from this page and paste it into the EiffelStudio editor pane. Build a system using these two classes, and {APPLICATION}.make as the root.
Note: If you are using EiffelStudio version 6.3, there two things you will need to do to prepare your system for use with AutoTest. Both of these are done from the EiffelStudio: Project settings window.
1) Set your project to be a console application in the Advanced options.
2) Set a value of False for the Recursive attribute of your project cluster in Group options.
If the AutoTest interface is not on a tab next to Clusters, Features, and Favorites, you can invoke it by following the menu path:
View --> Tools --> AutoTest
To begin the process of creating a new test, click the Create New Test button (
) on the interface's tool bar. When you click this button, by default AutoTest will set you up to create a new Manual test. To choose a different test type, click the small triangle to the right of the Create New Test button and you'll be presented with a drop-down menu of choices:
For now, let's select Create Manual Test.
If this is the first time you've used the testing tool for this project, it is likely that you will be presented with a dialog box asking if you want to add the testing library classes to your project and recompile:
You want EiffelStudio to do this before launching the wizard so, click "Yes". In a moment your system will have recompiled with the testing library classes available. Remember that you won't need to interact much with the testing classes, but AutoTest uses them, so they need to be available. As long as the testing classes stay available, you should not see this dialog again for the current project.
After the compile completes, then the first pane of the New Eiffel Test Wizard appears. It's the Manual Test pane and should look like this:
Here we will name our test. Let's say that we plan to write this test against the feature {BANK_ACCOUNT}.deposit. We'll give this test the name test_deposit_01. The name uses an ad hoc naming convention for tests. You can use this, or develop your own. The prefix test_ comes before the feature name it will test, and the suffix _01 follows, so that we have a framework for adding more tests against deposit. Again, you can choose any naming scheme that makes sense to you. You may want to try to describe the test in its name. For example, test_deposit_very_large_amount.
We're ready to click Next, but before we do, let's look at the check boxes on this wizard pane. The two check boxes labeled Redefine `on_prepare' and Redefine `on_clean' have to do with the way that tests are run.
AutoTest runs each test as a three step process:
There are features in class EQA_TEST_SET named prepare and clean which accomplish steps 1 and 3 above. These features are frozen, therefore you cannot redefine them in a test class (i.e., a descendant of EQA_TEST_SET) However the class does provide features that can be redefined so that you can include custom behavior before and/or after the execution of a test. These features are on_prepare and on_clean. So if you check one of these boxes, then the test class that is built for you will include a redefined feature ready for you to implement. In this simple example, we'll leave both boxes unchecked.
Note: The check box labeled System level test is displayed here as not sensitive. This box is reserved for future system level testing capability in AutoTest, so for versions including 7.0, you can ignore it.
Another thing to notice before we click Next, is that at this point we could click Launch. Launch will immediately try to create the test with the information it has available. The idea is that if you are creating several similar tests, you can change the test routine name and leave the rest of the information as you had entered it on a previous test. This keeps you from having to traverse the wizard panes entering the same information repeatedly.
But in our case, we need to use the subsequent wizard panes, so let's click Next, to go to the next one.
With this pane, you identify tags for your test that allow you to manage your test set more easily in the future. Read more in About Tags below.
For this test, we will include only a tag that identifies the class and feature covered by the test. To do this we click Add tag for covered class/feature. When we do, we are presented with a dialog in which we can choose a class and feature.
We'll choose class BANK_ACCOUNT and feature deposit, click OK.
Now you should see the coverage tag in the list of Tags used in new test.
That takes care of adding our coverage tag, so let's click Next to go to the next wizard pane, the General pane.
We will use this wizard pane to name our test class and let AutoTest know where we want the test class to reside. You can give a test class any name you wish, as long as it doesn't conflict with another class name in your system. If you try to type in a class name that already exists, the wizard will let you know right away by changing the text color to red. There is a convention that has arisen around test class names. If possible make the test class name the name of the target class, prefixed with TEST_. So in our case, we want to build a test against a feature of the BANK_ACCOUNT class, so we will name our test class TEST_BANK_ACCOUNT.
Now, for the question of where the tests should be kept.
By default, tests will be stored in a subdirectory of the EIGENs directory that is generated by the Eiffel compiler. Because it's the default, it's the quickest, easiest way to house tests. But it may not be the best for you in the long run. For example, if you manually delete the EIFGENs directory, which is occasionally necessary, you will lose your tests.
You could include them in the same cluster as some of your application classes. But there are some advantages to keeping the test classes in a test cluster separate from your target classes. For example, it will be easier for you to deliver your application or library classes if the testing classes aren't mixed with your domain classes. A test cluster is just a cluster of classes that EiffelStudio and AutoTest expect to contain test classes. So, in our case, let's create a new testing cluster as a subcluster of the cluster in which the classes APPLICATION and BANK_ACCOUNT reside.
First, uncheck the box labeled Use EIFGENs cluster.
Notice the New cluster link on the General pane. We click that link to add a new test cluster. The Add Cluster dialog box appears:
We can name our test cluster tests, the default, and make it a subcluster to our root cluster accounts. Notice that there is a test cluster check box on the dialog. It is checked and disabled, so at this point in the wizard you would always create a test cluster. Let's also check the box labeled recursive. Once the test cluster is created, we're back to the General pane which now looks like this:
At this point we have provided all the information necessary for AutoTest to create the shell for a manual test on the deposit feature of the BANK_ACCOUNT class.
So, now we click Launch, and AutoTest creates our test set and test.
Let's look at the class TEST_BANK_ACCOUNT:
note description: "[ Eiffel tests that can be executed by testing tool. ]" author: "EiffelStudio test wizard" date: "$Date$" revision: "$Revision$" testing: "type/manual" class TEST_BANK_ACCOUNT inherit EQA_TEST_SET feature -- Test routines test_deposit_01 -- New test routine note testing: "covers/{BANK_ACCOUNT}.deposit" do assert ("not_implemented", False) end end
We can see that the feature test_deposit_01 exists, but doesn't really test anything. So, let's change that. We'll alter test_deposit_01 so that it creates an instance of BANK_ACCOUNT and then makes a deposit to that account.
So, test_deposit_01 now looks like this:
test_deposit_01
-- New test routine
note
testing: "covers/{BANK_ACCOUNT}.deposit"
local
l_ba: BANK_ACCOUNT
do
create l_ba
l_ba.deposit (500)
end Now we have created and written a manual test using AutoTest.
Next let's look into the notion of Tags in a little more detail, then see what it takes to execute a test.
The Tags pane allows us to associate our test with any AutoTest tags that we feel are appropriate.
Tags are simply names or otherwise meaningful strings of characters that are arranged hierarchically and can be associated with a test to help manage, maintain, execute, and monitor its results. Any one test can support many tags. It is quite likely that during the development process, your system may eventually accumulate a great number of tests. And you may want only to execute some selected portion of those tests at any particular time. Tags allow you do that with the help of AutoTest.
One of the most common types of tags specifies what class and feature a test covers. In our example, we wrote our test against the deposit procedure of the class BANK_ACCOUNT. The tag that we added to express this is:
covers/{BANK_ACCOUNT}.deposit
deposit and withdraw, then its list of tags would be:
covers/{BANK_ACCOUNT}.deposit covers/{BANK_ACCOUNT}.withdraw
covers either deposit or withdraw, this test would show up in that set.
The "covers" tags, as you saw earlier, can be generated by AutoTest's New Eiffel Test Wizard when you create a new test. But you could enter the tag manually, as well. For example if you had written a high level test that exercised all or most of the functionality of the class BANK_ACCOUNT, you could manually add a tag that expresses that, i.e., a "covers" tag for BANK_ACCOUNT that does not specify a particular routine:
covers/{BANK_ACCOUNT}
Tags can be completely arbitrary, too. So, for example if you were building software that you expected to run on multiple platforms, in the test suite, you might have a test with the following tags:
platform/os/linux platform/architecture/i386
Looking again at the Tags pane, you will see that there are two boxes under the label Tags used in new test. The first is just a display of the list of tags that you have added to the new test. The next box down allows you to add an arbitrary tag sequence like:
platform/os/linux
{BANK_ACCOUNT}.deposit.
In addition to Add tag for covered class/feature, choices for other predefined tags are shown as links. For example, Add tag to run test in private evaluator and Add tag to run test serially.
Selecting Run test in private evaluator will insert the tag:
execution/isolatedWhen tests are executed, they do so within the context of evaluator processes. Normally, evaluator processes are reused for multiple test executions. But if you select Run in private evaluator, the tag added to your test guarantees that this test will be run in a fresh evaluator process, that terminates when the test completes. This can be helpful, for example, when you don't want your test to enter or leave the evaluator process with the effects of "once" routines or any other action that might effect the efficacy of other tests. For example, if your test executes external routines which might have a damaging effect on memory, you should run the test in a private evaluator.
If you select Run test serially, the following tag will be inserted:
execution/serialTests tagged with this tag will not run concurrently with any other similarly tagged test is running.
You can extend the serial execution tag with arbitrary terms that will differentiate groups of tagged tests. For example, if some of your tests are tagged like this:
execution/serial/group_1
execution/serial/group_2
group_1 tagged test concurrently with any other group_1 test, and likewise for tests tagged group_2.
In the previous section we coded a manually created test. AutoTest will allow us to execute that test, or, in more practical terms, any set of tests that we select. But before we execute our test, let's take a look at what we will get out of such an execution.
Contents
|
It is important to understand that for AutoTest, test results are solely determined by whether an exception occurs during the execution of a test, and, in cases in which an exception does occur, what kind of exception it is. So, with AutoTest, it is not necessary for you to write anything special into a test that propagates the test's results.
When AutoTest executes a test, the result will be one of only three possibilities:
These possibilities are defined as follows.
Definition -- Successful test: A test which has executed without causing and exception to occur.
Definition -- Failing test: A test which has caused an exception to occur during its execution, specifically during the execution of a target routine.
Definition -- Unresolved test result: A test which has caused an exception to occur during its execution, but exclusive of the execution of a target routine.
So, successful tests are easy enough to understand. The test executed with no exception.
Failing tests and unresolved test results both mean that an exception occurred during the execution of the test. The distinction is made based on the location of the feature that causes the exception.
When we execute our test {TEST_BANK_ACCOUNT}.test_deposit_01, we know that test_deposit_01 will make a call to {BANK_ACCOUNT}.deposit. If the exception occurs during the execution of a target routine (i.e., in {BANK_ACCOUNT}.deposit), then the test is considered failing. If the exception occurs anywhere else in the execution of {TEST_BANK_ACCOUNT}.test_deposit_01, then the test is considered to have an unresolved result.
Note: Be aware that some early versions of AutoTest reported some unresolved test results as failing tests.
This behavior can be helpful to us as testers. A failing test indicates that there is something amiss in the target routine. The routine has not completed in a state that satisfies its postcondition and class invariant, or is dealing with an unresolved exception from some routine that it has called. An unresolved test result indicates that something is amiss in our test. Something went wrong in the setup or cleanup of the test or perhaps the test called a target routine from a state that did not satisfy the target routine's precondition.
In the last section, we created a manual test. The AutoTest tool shows us the new test in the Tests column. So, now the tool should look something like this:
You see under "Tests" the project cluster accounts, the test cluster tests, the test class TEST_BANK_ACCOUNT, and the test test_deposit_01. You might have to expand some of the elements to see everything as shown above.
You see that the Status of test_deposit is "not tested", and that the Last executed date is empty.
To execute tests we use the "Run" button (
) on the interface toolbar. By default, the Run button will run all tests matching the tags in the Filter box. However, there is a list of run options that you can access by clicking the black triangle just to the right of Run. You can choose to run all tests, only those with failing status, a filtered set of tests, or only those tests that you have selected in the tree below. We'll cover filtering a little later. For now, life is simple, we have only one test so just selecting Run all should execute it.
The test runs in background and the AutoTest interface now looks like this:
It's pretty clear that our test has failed. Its status is now marked with the Failing icon (
) and in the box below the Execution tab we see that the status also includes a tag: balance_increased. More detail is provided in the Testing pane of the Outputs tool, as shown below.
We see that balance_increased is a postcondition tag on the target routine {BANK_ACCOUNT}.deposit. Upon examination of the code:
deposit (an_amount: INTEGER) -- Deposit `an_amount'. require amount_large_enough: an_amount > 0 do ensure balance_increased: balance > old balance deposited: balance = old balance + an_amount end
we realize that there is no implementation here. So we add the code to implement deposit:
...
do
balance := balance + an_amount
ensure
...After compiling, we can execute the test again. We could do this by selecting Run all as we did last time, or by selecting Run failing. Once the test executes we see now that it was successful:
This time we see that the test is successful, as indicated by the Success icon (
) in the Status column.
Of course we would not have had to use AutoTest to find that bug in {BANK_ACCOUNT}.deposit. We could have just written a simple class to exercise instances of BANK_ACCOUNT and truth would have come out.
The advantage of using AutoTest is that the test that we wrote to cover {BANK_ACCOUNT}.deposit can stay with us throughout the lifecycle of class BANK_ACCOUNT. We can expand the TEST_BANK_ACCOUNT with additional manual tests and run them after every development increment to ensure that all tests that were once successful are still successful.
We have seen how to create and execute a manual test. You will find that manual tests form the backbone of your test suite. But there are two other types of tests available in AutoTest. Next let's take a look at these test types and in what ways they can be used.
Contents
|
At any time that you are running a system in EiffelStudio debugger and your system is paused, you can ask AutoTest to extract a new test class and test from the current executable context. Most often you would use this capability in the case in which you experienced an unexpected failure or exception in one of your routines. It is possible, though, to extract at any point at which the system is paused.
The value of extracted tests is that they provide a kind of a snapshot in testing form that will reproduce the unexpected failure. An extracted test attempts to reproduce the context in which the offending routine executed. So, extracted tests supplement your manual tests. They serve to cover situations which you just may not have written manual tests to cover.
Extracted tests are intended to supplement the suite of manual tests that you have created to do the bulk of your testing. So, usually when you create an extracted test, it happens as a result of your being surprised. You will notice that each time you create an extracted test, you get a new test class, too. This is in contrast to manual tests, in which you might use the wizard to create a new test class and one new test to cover a particular target class and target routine. Then you might manually create, in that same test class, many additional tests covering the routine behavior of the same or other target routines in the same target class.
Let's use the same test system we used for manual tests to demonstrate the creation of an extracted test. The example will be slightly contrived because it will find a problem that certainly we would already have discovered had we written a comprehensive set of manual tests against the BANK_ACCOUNT class. Still, the simplicity should help keep things clear.
If you remember, the root class for the example application was not very interesting, just a root procedure with a single instruction and a declaration my_account of type BANK_ACCOUNT:
make
-- Run application.
do
create my_account
end
my_account: BANK_ACCOUNT
Now, let's add some code into the make procedure that will make use of my_account:
make
-- Run application.
do
create my_account
my_account.deposit (500)
my_account.withdraw (100)
end
If we run the application from EiffelStudio, we see that it stops when it incurs a postcondition violation in {BANK_ACCOUNT}.withdraw:
When we look at the feature pane, it's pretty easy to see where the problem is:
There is an error in the specification for withdraw. In the postcondition tagged withdrawn, the plus sign should have been a minus sign. Therefore, the assertion should read like this:
withdrawn: balance = old balance - an_amount
Certainly we will fix this, but AutoTest gives us the opportunity to extract a test based on this particular failure. So, let's do that.
So, we go to the AutoTest tool and click triangle next to Create new tests button and select the Extract tests from debugger from the drop-down menu. Because we are paused in the debugger, the drop-down menu appears with the Extract tests from debugger choice enabled this time:
When we select Extract tests from debugger, we are presented with the New Eiffel Test Wizard's Test Extraction pane. This wizard pane shows a depiction of the current call stack and asks us for which feature(s) on the stack we want to create the test:
The choice for withdraw is the selection we want. We can deselect the stack frame for make if it is pre-selected. If we click Next at this point we would be taken to the Tags pane, and from there to the General pane. But we really don't need to do this. AutoTest will sense that we are extracting a test for {BANK_ACCOUNT}.withdraw and tag the test properly. It will use the same test class name from the General pane, but add a numerical suffix. So, all we need to do now is to click Launch from the Text Extraction pane.
AutoTest creates the new test and returns us to the debugger, where our system is still on hold. We can stop execution and compile to include the new test.
Now we see the new test class and test in the AutoTest tool windows.
We run our tests using Run all, and we see that the test on withdraw is still failing:
If we fix the error in the postcondition in withdraw, recompile, and then re-execute the test, we find that it is successful.
Look at the code that was generated for the extracted test after the assertion violation occurred:
note description: "Regression tests reproducing application state of a previous execution." author: "Testing tool" class TEST_BANK_ACCOUNT_EXTRACTED_WITHDRAW_01 inherit EQA_EXTRACTED_TEST_SET feature -- Test routines test_withdraw note testing: "type/extracted" testing: "covers/{BANK_ACCOUNT}.withdraw" do run_extracted_test (agent {BANK_ACCOUNT}.withdraw, ["#1", {INTEGER_32} 100]) end feature {NONE} -- Access context: !ARRAY [!TUPLE [type: !TYPE [ANY]; attributes: !TUPLE; inv: BOOLEAN]] -- <Precursor> do Result := << [{BANK_ACCOUNT}, [ "balance", {INTEGER_32} 400 ], False] >> end end
You probably noticed immediately that it doesn't look much like the code that we wrote for our manual test in the previous section.
One reason for the difference is that the class does not inherit directly from EQA_TEST_SET as our manual test did. Instead, it inherits from EQA_EXTRACTED_TEST_SET which itself is a descendant of EQA_TEST_SET. EQA_EXTRACTED_TEST_SET provides additional functionality for extracted tests.
Notice that the call to the target routine {BANK_ACCOUNT}.withdraw is effected in the routine test_withdraw which passes an agent representing {BANK_ACCOUNT}.withdraw to the procedure run_extracted_test. The second argument to run_extracted_test is a TUPLE with the argument values which were used in the call to withdraw which caused the original assertion violation.
Another thing worth noting is the function context. This is how AutoTest recreates the state of the instance of BANK_ACCOUNT at the time of the assertion violation.
Caution: The extracted test recreates the state at the point at which execution has halted. So, in the case of a postcondition or invariant violation, the values of the attributes will reflect any changes that have been made during the execution of the routine. (In the example, the value of balance is set to 400, rather than 500 as it would have been when routine withdraw began execution.) This could make a difference in whether the test extracted after an exception is a valid recreation of the original failure. One way of dealing with this, at least in simple cases like this, is to change the test class code to reflect the proper value. A safer way would be rather than extracting the test after the exception, restart the system and stop execution as it enters the failing routine, then extract the test at that point.
Generated tests fill a different role from either extracted or manual tests. The idea behind generated tests is that because we specify software through its contracts, and because compliance of the software to those contracts can be actively monitored at runtime, we can know two things necessary for building tests:
The first bit of knowledge comes from the preconditions of target routines. The second comes from postconditions of target routines and the invariants of target classes. Armed with this knowledge, we should be able to generate a series of invocations of target routines using random argument values, and evaluate the results. This is what is done by an internal facility of AutoTest that builds generated tests (this facility is often also referred to itself as AutoTest). After many of these randomly generated invocations, AutoTest attempts to synthesize the results of these feature calls into new test classes. The tests in these new test classes contain the calls leading up and including calls that fail. AutoTest will attempt to create only one test from each unique type of failure, so that your test directory doesn't get loaded with lots of duplicate tests.
You may look at a generated test class and think that it seems to be very long and to contain lots of stuff that you doubt is relevant. This is a fair assessment. The processes that AutoTest uses to build and minimize generated tests are constantly being improved. But for now, generated tests, although useful, retain a certain amount of that randomness that was used in their creation.
So for the time being, unlike manual and extracted tests, you should not make generated tests a part of your permanent test suite. Rather, you should consider them a disposable means to an end. Use each generated test as a guide for building an effective and readable manual test.
If you've been through the discussion of the creation of manual and extracted tests, then it should come as no surprise to learn that you use the New Eiffel test wizard to create generated tests. And much of this process will seem familiar now.
In the drop-down menu for the Create new test button, choose the item Generate tests for custom types.
At this point, you'll see the Test Generation wizard pane. This pane allows you to specify which classes you want to generate tests for. You can also adjust the values of certain parameters used in the test generation.
Let's type the class name BANK_ACCOUNT into the box labeled Class or type name and click the "+" button to added it to the list. Of course you can remove an item from the list by selecting it and clicking "-".
The rest of the pane is used to configure certain options for the test generation process.
Cutoff (minutes) lets you specify a number of minutes for AutoTest to run random invocations of the routines in your target class(es).
Cutoff (invocations) lets you control how long AutoTest will run random invocations by declaring a specific number of invocations.
Routine timeout sets an upper limit on how long AutoTest will wait for a random feature call to complete.
Random number generation seed provides a way for you to control the seeding of the random number generator used by AutoTest. When the value is 0, as shown here, the seed is created from the system clock. This is adequate in most cases, but this option is provided because there might be some cases in which you would want to try to reproduce a previous test generation run. And to do that, you would have to set the seed to the same value for multiple runs.
The two check boxes Slice minimization and DDmin for minimization allow you to select the approach that you want to use for minimizing the size of generated tests. Generally, the default value here is adequate. Slicing and ddmin are two different ways of doing minimization. Tests are generated after running many randomly generated calls to routines in your target class. Tests are generated for calls that fail. So, there may have been many randomized calls leading up to the failed call. Minimization helps to eliminate the majority of the unrelated randomly generated calls, leaving the test code as short as possible. You will notice that minimization processing is memory and processor intensive.
The last check box, HTML statistics gives you the option of having AutoTest record the results of a test generation run in a set of files that you can review with a web browser.
We can allow all these to remain their default values, with one exception. Let's check the HTML statistics box.
During the test generation you can watch the random invocations of your class's routines being logged in the Testing pane of the Outputs tool. When the generation completes, AutoTest directs you to the location of the results:
The file statistics.txt contains a summary of the generation run. If you enabled Create HTML output you can open the file index.html with your browser and view formatted summary and detail information.
Note: The result directory includes files that summarize the whole generated testing process. Some of these are lengthy because they contain information on test cases used for each target routine.
If we try to generate tests on the class BANK_ACCOUNT in which we have already fixed two bugs after the manual and extracted tests, we will see something about like the following results:
The important thing to notice here is the status: pass. There were no randomly generated cases that failed. So every valid invocation of a routine for class BANK_ACCOUNT completed satisfactorily. Therefore, no generated test class was created.
If we re-introduce the bug into the deposit procedure of class BANK_ACCOUNT (i.e., Remove this line of code: balance := balance + an_amount), and then request generated tests again, we get different results:
This time, as we expected, failures were encountered. And a generated test class was created.
The generated test class looks like this:
note description: "Generated test created by AutoTest." author: "Testing tool" class TEST_BANK_ACCOUNT_GENERATED_001 inherit EQA_SYNTHESIZED_TEST_SET feature -- Test routines generated_test_1 note testing: "type/generated" testing: "covers/{BANK_ACCOUNT}.deposit" local v_6: BANK_ACCOUNT v_7: INTEGER_32 do execute_safe (agent: BANK_ACCOUNT do create {BANK_ACCOUNT} Result end) if {l_ot1: BANK_ACCOUNT} last_object then v_6Â := l_ot1 end v_7Â := {INTEGER_32} 3 -- Final routine call set_is_recovery_enabled (False) execute_safe (agent v_6.deposit (v_7)) end end
Note: If you've been following along by the doing these examples in EiffelStudio, you may notice that your generated class looks slightly different.
This test is written in a way that is a little different from both the manual test we wrote and the extracted test. But it's not too hard to figure out what's going on. An object of type BANK_ACCOUNT will be created (local v_6) and the deposit feature will be applied to it with an argument value of 3 (local v_7).
You can see that this test, although it is implemented differently, is about the same as the manual test we wrote covering {BANK_ACCOUNT}.deposit. Because we have re-introduced the bug in BANK_ACCOUNT, if we run all tests, we see that both our manual test and the generated test are failing ... only the extracted test covering {BANK_ACCOUNT}.withdraw is successful:
If we replace the implementation for {BANK_ACCOUNT}.deposit that we had removed, and then re-execute the tests, all are successful.
The previous sections cover the basics of testing and what it takes to create and use each of the test types supported by AutoTest. This section will finish things up with some miscellaneous information about testing strategy and hints on using AutoTest.
Contents
|
It is worth repeating that currently, manual tests should form the majority of your testing suite. As you have seen, extracted and synthesized tests use more complex setup and execution mechanisms. These mechanisms make tests less robust and readable than manual tests. So using extracted and synthesized tests as a guide to produce manual tests with the same coverage is, at this time, the best way to work. You will probably be able to do this easily enough with synthesized tests. Extracted tests attempt to recreate the context at a specific point in time, which may make it more difficult to write a manual test that is equivalent an extracted test.
Because manual tests are more easily readable than either of the automatically generated test types, you should be able to understand more quickly what has happened when a test produces failing results.
At some point and for various reasons, you will probably want to delete tests from your test suite. This is easy enough to do. Remember that test sets are actually just classes with certain characteristics, and that tests are actually just specialized routines of test classes.
If you want to delete a single test, you can delete that feature from its test class.
If you want to remove a whole test set, then delete the class that defines that test set.
Filtering is provided to help view, manage, and run the tests in a test suite.
Filtering controls which tests are visible in the AutoTest interface how the view is organized. You can display tests organized by the test classes that contain them, by the classes they target, by their type, by their most recent results, or by any system you set up using a system of tags.
Filtering helps you manage which tests get run during a give execution. You can select certain tests to be run from those visible in the AutoTest interface, or you can choose to run all tests visible through a filter.
The Filter box in the AutoTest interface can be used to enter filter text which will allow only certain tests to be visible.
Filter text can be a string of characters occurring in specific test class name or test routine name, or it can be a tag or a portion of a tag hierarchy. The Filter box supports regular expressions, so you can filter with more granularity.
It is important to bear in mind that the View box works with the system of tags described in the section on creating manual tests. Tags are hierarchically structured names that are applied to tests through the note clause. When you use the View box to display a set of tests, you specify that set by the tags on the tests. Some of the tags are implicit, in the sense that AutoTest accounts for them, and they are not explicitly coded in note clauses. This should become clear when we look at some examples.
When the filter text is cleared, the AutoTest interface will display tests accessible through all tag roots.
As of version 6.5 of EiffelStudio, the tag root words used are:
| class | Tests organized by test classes |
| covers | Tests organized by target classes/routines |
| result | Tests organized by the results of their most recent execution |
| user | Tests organized by type (manual, extracted, generated) and by user-added tag hierachies |
Note: The tag roots will appear only if there are tests that can be categorized under them. For example, if you have not run any tests, then result will not appear.
Notice that the Filter box has a drop-down with a list of options:
These options are shortcuts to the various tag roots listed above:
Any tagging system that you devise will show up under the user tag root.
For example, consider a manual test containing a testing: note name with a user-defined tag as in the following code.
test_deposit_01
-- New test routine
note
testing: "covers/{BANK_ACCOUNT}.deposit"
testing: "my_tag_root" -- My new tag root
local
l_ba: BANK_ACCOUNT
do
create l_ba
l_ba.deposit (500)
endThis will cause the new user-defined tag and its associated tests to be visible in the AutoTest interface.
See Also: The Filtering section in The AutoTest interface.
In earlier sections we saw how EiffelStudio provides extensive documentation on your systems. That information was qualitative. Project managers and developers will also be interested in quantitative information about their projects. You can get such information through the Metrics tool, which enables you to perform a number of operations, detailed over the next few pages:
Although the field of software metrics is a rich one with an abundant literature, its methodological basis is sometimes subject to question. One should resist the tendency to believe numbers just because they are numbers ("lies, damn lies, and metrics").
Software engineers and their managers expect, however, to reap at least some of the benefits that precise quantification has brought to other engineering fields. Such is the purpose of software metrics, defined as quantitative estimates of product and project properties. Object-oriented development, with the rich software structures that it induces, is a particularly amenable to metric analysis. Even when some of the measures do not seem to bring much by themselves, comparing them to those of other projects may reveal significant peculiarities of a system or of some of its parts.
The metrics capabilities of EiffelStudio were designed with these observations in mind. They result from a conservative approach, where no metric is provided without a credible assumption that it reflects some meaningful project or product attribute. For example, you will find a way to define a new metric as a linear combination of existing ones, but not a way to compute arbitrary arithmetic operations, since it isn't clear that -- say -- multiplying two metrics ever makes sense.
The following terms are used in the presentation of EiffelStudio metric mechanisms.
A metric -- not to be confused with a measure -- is a quantitative property of software products or processes whose possible values are numbers. A measure is the value of a metric for a certain product or process.
For example, we can evaluate the metric "number of classes in the system", called just Classes, by counting the classes in our system. This yields a measure.
We may distinguish between product metrics, which measure properties of the elements being turned out (code, designs, documentation, bug reports...) and process metrics, which measure properties of the process used to turn them out (salaries, expenses, time spent, delays...). The current metric facilities of EiffelStudio are primarily product-oriented but include a process metric: "number of compilations".
Any metric should be relevant: related to some interesting property of the processes or products being measured, such as cost, estimated number of bugs, ease of maintenance...A metric theory is a set of metric definitions accompanied with a set of convincing arguments to show that the metrics are relevant. Neither EiffelStudio nor this manual provide a metric theory.
The numbers yielded by measures are meaningless unless we describe what they refer to. Every metric is relative to a certain unit, specified as part of its definition. For example the unit for a metric that counts classes, such as Classes, is called class.
EiffelStudio provides a set of predefined units. Some simply serve to count occurrences of certain construct specimens in the software; examples include group, class, feature, line, ... The metric ratio describes metrics whose values are divisions, for example "average number of classes per cluster", obtained by dividing the number of classes by the number of classes.
A metric can be computed over a scope. This scope is defined using a domain. A domain is a set of program elements. You build up a domain by adding development objects to a list. These development objects are things like application targets, clusters, libraries, classes, and features.
The following links will take you out of the Guided Tour and into the EiffelStudio Reference:
See Also: The EiffelStudio Reference section on the Metrics Tool for more comprehensive discussion and precise definitions of terminology.
So far the project modifications that we have made used the text editor in the Editing Tool. Now let's look at EiffelStudio's ability to provide a graphical depiction of our software system.
In line with the principles of seamlessness and reversibility recalled at the beginning of this Tour, EiffelStudio's interaction between text and diagram access to software is bi-directional. When you make a textual modification, the next incremental recompilation will update the diagram; but you can also work directly from the diagram, and the text will be generated or updated after each graphical operation.
Many people like to use the graphical mechanisms at the beginning of a project, to draft the overall structure of a system in "bubbles-and-arrows" style, then concentrate on text as they get closer to implementation. But there is really no such obligation. At any point in the development, just use the form that is more suited to your taste and to your needs of the moment.
Contents
|
We are going to play with the root cluster. So, we can work from EiffelStudio's default tools layout. Remember that you can reset the tools layout to the default by following the menu path:
View --> Tools Layout --> Reset Tools Layout
TESTROOT. So to start out, your Development window should look about like this:
Before getting started, another thing we want to do is to make sure that the the tools are in "Unlinked" mode; you can see this by going to the Edit menu: you will see either a menu item Unlink context tool (if tools are currently "Linked") or an item Link context tool (if tools are currently "Unlinked"). So if you see Link context tool, you don't have to do anything. But if you see Unlink context tool, then select that item to unlink the tools.
Let's start working with cluster views, showing the content of a cluster. Make the Diagram tool visible: move your cursor over (or click on)
at the bottom of the Development Window. You may want to float the tool away from the Development Window or "pin" it open (as we learned in the section on docking, and then maybe enlarge the tool some. You should see a graphical rendition of the root_cluster in the Diagram tool, something like the figure below. In the case that root_cluster is not visible, click the Target to class or cluster button (
) on the Diagram tool's toolbar.
First we might decide that we don't want to be bothered with class INVALID. We could delete it altogether from the system by a pick-and-drop of its bubble to the Delete (
) hole. This is not what we want, but try this now to see the confirmation request:
Make sure to answer No to that confirmation request (you want to keep the class even though it wouldn't be a catastrophe to lose it). Instead pick-and-drop the INVALID bubble into the Hide figure (
) hole. This time there is no confirmation request, since the operation is reversible -- it just affects what's displayed in the cluster view -- and the class is removed from the display:
You can try undoing this change (
), then redoing it (
).
You can also click the History icon (
) which, during the rest of the session, will display the list of executed operations, and let you undo or redo many operations at once by clicking the oldest to be kept or the youngest to be redone.
For the rest of this discussion we assume INVALID is hidden.
We are now going to add a class graphically to our system. This means you don't have to worry about creating and initializing a file; EiffelStudio will take care of the details.
The useful button here is Create new class:
When you click this button you'll see the Add New Class dialog box:
Overwrite the default class name being proposed by the name HEIR2, as we are going to create a new heir of PARENT. Now click the button labeled Create.
The new class is created and added to the diagram as part of root_cluster:
Using conventional drag-and-drop (not pick-and-drop), move the class bubbles for HEIR2, TESTROOT and PARENT so that the display looks approximately like the following. The double circle around TESTROOT is the BON (Business Object Notation) convention to identify a system's root class.
Now we are going to make HEIR2 an heir of PARENT. To create relationship links between classes you pick-and-drop from the source class, but don't do that yet. First we have to specify that we want an inheritance relationship.
By default, the new relationship Creation Mode will be client/supplier (
). To change the creation mode to inheritance, click on the selection triangle next to the new client/supplier link icon, and choose Conforming inheritance Creation Mode ... from the drop-down menu, as shown below.
Notice that the current Creation Mode icon has changed to indicate conforming inheritance (
).
Now pick-and-drop from the HEIR2 bubble to the PARENT bubble. (Now you see why conventional drag-and-drop is used to move bubbles: pick-and-drop on the diagram serves to add links between classes).
To convince yourself that the new class has been made an heir of PARENT, not just in the diagram, but in its text as well, you can look at the class in an Editing tool. Unless you are so fortunate as to have plenty of monitor space, you may have to un-pin the Diagram tool to be able to see the Editing pane. Pick-and-drop HEIR2 bubble to the Editing tool to see its text.
The code for a minimal class HEIR2 has been generated from your graphical operations: creating the class produced a class template, and the creation of the new inheritance link made HEIR2 inherit from PARENT.
In a moment we'll use this Editing Tool to see how, conversely, EiffelStudio will automatically reflect in the diagram a change made to the text.
For now, make sure the Diagram tool is visible again.
Next let's make TESTROOT a client of HEIR2.
First, re-select Client-Supplier' as the Creation Mode for new links.
Pick-and-drop from the TESTROOT bubble to the HEIR2 bubble. This causes the New Feature dialog box to appear:
This technique gives you many option and in fact is a convenient way to build your classes, whether at the analysis, design or implementation level. Here, fill the fields as follows. For the top choice, keep the default, Attribute; we'll give class TESTROOT an attribute of type HEIR2. For its feature category, keep the choice currently displayed, Access. For its name, replace the default, by the name o3. In the invariant box, choose
o3_not_void: o3 /= Void
from the list to specify the invariant property that this attribute should never be void. Finally, to see how EiffelStudio can generate the full accompaniment to an attribute, in the box Setter? choose
set_o3
This will create a routine with this name which clients can use to set the value of o3.
You may have noticed that the checkbox labeled Assigner? became enabled when you chose a name for the Setter. This will make the setter routine be called if a client uses an assignment of the form:
my_testroot.o3Â := some_value
The assigner makes this is a syntactical shortcut for writing:
my_testroot.set_o3 (some_value)
Without the assigner, the direct assignment by a client would result in a syntax error, because in Eiffel clients are prohibited from assigning directly to their suppliers' attributes.
So, check the Assigner? box.
Now, click OK.
The diagram now shows that TESTROOT is a client of HEIR2.
Now, if you'd like, you can check the text of TESTROOT as we did earlier with HEIR2, but here are the highlights:
You'll notice that the attribute o3 has been added under the feature category "Access":
feature -- Access o3: HEIR2 assign set_o3 -- `o3' attribute Result := ({like o3}).default end --| Remove line when attached attribute is correctly assigned
After the attribute declaration the keyword assign declares that the feature set_o3 is to be called when assignments are made to o3 by clients.
You see that the header comment is trivial ( -- `o3' ), simply echoing the feature name. This is because we failed in our duty to fill in a reasonable header comment in the New Feature dialog. Every feature should have a meaningful header comment.
Now notice the last line, beginning with the keyword attribute. This line is intended to be temporary. It makes your new attribute o3 a self-initializing attribute, which just allows you to avoid certain errors until you insert code to initialize o3 properly.
The "setter" routine for o3 is generated and categorized as "Element change":
feature -- Element change set_o3 (an_o3: like o3) -- Assign `o3' with `an_o3'. require an_o3_not_void: an_o3 /= Void do o3Â := an_o3 ensure o3_assigned: o3 = an_o3 end
Notice that EiffelStudio has included both a precondition and postcondition for set_o3.
Also, a clause has been added to the class invariant to ensure that set_o3 is not void:
o3_not_void: o3 /= Void
The situation here is different from what we saw earlier with HEIR2, which had been generated from scratch by the diagram. Here TESTROOT existed before, in text form; so the diagram mechanisms have had to preserve the existing feature and feature clauses, and add the elements corresponding to what you have specified through the diagram mechanisms. The unlabeled Feature clause of the existing class has been kept; the new features have been entered into clauses labeled Access and Element change, observing the Eiffel standard for common feature clauses in libraries.
In this tour of the diagram facilities we have, so far, worked on the diagram and seen the text updated immediately. Of course we want full reversibility. So let's make a change in the text and check the diagram.
The change will be very simple. We'll make TESTROOT a client of HEIR. In the Editing tool, add an attribute declaration
other: HEIRNow save the file by clicking the
icon.
Nothing happens yet to the diagram. This is normal: EiffelStudio doesn't update the diagram every time you type some text (which, for one thing, might be syntactically incorrect, or invalid). You need to recompile first. Click the
button. Then the new relation appears:
If the label other of that relation doesn't appear in the exact place shown here, try moving it using conventional drag-and-drop. You can only move such a link label within a small area on either side of the link.
Earlier on, we saw how to create a class from the EiffelStudio diagram, letting EiffelStudio take care of creating and initializing the file. Similarly, you can create a new cluster graphically, and let EiffelStudio create the corresponding directory.
To create a cluster, you can go through Project settings, or you can do so directly from the Groups tool. Let's use the Groups tool. On the title bar of the Groups tool, you'll find the Add a cluster button (
). (You may have to expand the titlebar menu through its double chevron placeholder >>).
The resulting dialog asks you for the cluster name, and the existing cluster (non-precompiled) of which you want to make it a subcluster, here leaving only one choice:
Instead of the default name, type my_cluster; select the only possible supercluster, root_cluster, and click Create at the bottom of the dialog.
Now the diagram shows the new subcluster:
Try to make your display look approximately like the above; you will probably have to move (drag from the center) and/or resize (drag from a corner) either or both clusters.
Among the many operations you can do graphically is to move a class from one cluster to another. Pick-and-drop the HEIR2 class bubble to the rounded rectangle for MY_CLUSTER.
This graphical manipulation has caused a structural change: class HEIR2 is now part of MY_CLUSTER. Check this by expanding the Cluster Tree on the left:
If you like, you can also look into the project directory -- using the Windows Explorer, or cd and ls on Unix/Linux -- and check that it now has a subdirectory my_cluster with a file heir2.e containing the text of class HEIR2.
Clearly, it's much more convenient to use EiffelStudio for such manipulations than to move files around manually.
A number of buttons enable you to customize the display. So far all class bubbles had the same default color. Try pick-and-dropping a bubble into the Color hole (
) to get a color palette that enables you to select a different color. This is useful if you want to highlight classes possessing certain properties, for example classes that are part of a certain Design Pattern.
Relation depth (
) enables you to select the depth at which inter-class relations will be displayed. (Don't change this setting now.) Include all classes of cluster (
) is more useful for class diagrams than for the cluster diagram we have now, which by default included all classes of the cluster; if you click it here it will add the class INVALID that you removed earlier. There is no need to do this now.
So far the top-right View field has always shown DEFAULT:BON. You can define any number of views in your project, and apply them to various class and cluster diagrams.
For example, using the buttons to show and hide links of various kinds you can produce diagrams that only show the inheritance links, and others that only show the client links. If you want to keep both kinds of diagram, simply define views by typing view names -- such as Inheritance, Client, All_links -- into the View field.
You can also use views to retain some of the choices seen just before, such as different colors and depths.
To load a previously defined view, just use the menu associated with the View field.
You may remember that when we generated HTML documentation, the dialog asked you to select a view among the available ones. You can choose a different view for each cluster.
You may have guessed that the BON in DEFAULT:BON means that the diagram view is in Business Object Notation. You can also view diagrams in UML-style notation. To do this you would click the Show UML button (
). Click it again to return to the BON view.
In the present discussion we have used cluster diagrams. Both are interesting. To obtain a class diagram, you will target a Class tool to a class, and select the Diagram tool. By default, this shows the parents of the class. Do this now for TESTROOT.
Note: Because at the beginning of this page, we put the EiffelStudio context tools in "unlinked" mode, it may be necessary to synchronize the context to see the class diagram. You can do this by clicking Synchronize context (
) in the main toolbar.
It's for class diagrams that the Relation depth (
) button is most interesting. It will let you select the exact depth that you wish displayed for each relation type:
This will conclude our review of the Diagram facilities of EiffelStudio, although you'll surely discover some further riches by yourself and through the rest of the documentation. We hope the complete seamlessness between text and pictures will enable you to increase the effectiveness of your analysis work, or your design work, or your programming -- whatever level of system development you need to tackle.
You can use EiffelStudio to include a license text in each of your classes automatically. The automatic class licensing facility is flexible so that you can use various strategies to retrieve the license text used.
When you save the text of a class file in EiffelStudio, the automatic licensing facility searches for an appropriate license text file to use. If such a file is found, then EiffelStudio includes the contents of that file as an ending note part in your class. Here's the text of a class that includes an Eiffel Software license:
class APPLICATION inherit ARGUMENTS create make feature {NONE} -- Initialization make -- Run application. do print ("Hello Eiffel World!%N") end note copyright: "Copyright (c) 1984-2010, Eiffel Software" copying: "[ Duplication and distribution prohibited. May be used only with Eiffel Software products, under terms of user license. Contact Eiffel Software for any other use. ]" source: "[ Eiffel Software 5949 Hollister Ave., Goleta, CA 93117 USA Telephone 805-685-1006, Fax 805-685-6869 ]" end
Contents
|
License text should appear in a text file with the file type ".lic". The text should contain the note clause which includes the license text and nothing more. EiffelStudio will parse the text and invalid instances of license text will not be merged into the target class.
The following text is the content of the license text file which was used to annotate the class shown above:
${NOTE_KEYWORD} copyright: "Copyright (c) 1984-${YEAR}, Eiffel Software" copying: "[ Duplication and distribution prohibited. May be used only with Eiffel Software products, under terms of user license. Contact Eiffel Software for any other use. ]" source: "[ Eiffel Software 5949 Hollister Ave., Goleta, CA 93117 USA Telephone 805-685-1006, Fax 805-685-6869 ]"
Notice that a variable is used for the note keyword (to support the language keyword change from indexing to note). Also a variable for the current year is used in the copyright notice.
Where you keep your license text files depends upon which method you use to have EiffelStudio retrieve the license text from the files. Generally, license text is retrieved from files in one of three places:
This is the directory that contains your project configuration file, the ".ecf" file).
This directory is located at: $ISE_EIFFEL/studio/templates/licenses
This directory is located at: $ISE_USER_FILES/studio/templates/licenses
You can put a note in the source code of a class which will cause EiffelStudio to search for a corresponding license file and then include the license text from that file. Here's what such a note might look like:
note license_name: "OurLicense"
The license_name term should be placed in the top note clause of the class. (If you include in the bottom note clause, the license_name term itself will be removed when the class license gets replaced.)
In this case, EiffelStudio will search for the file `OurLicense.lic'. It will look first in the Eiffel user files license template directory, then in the Eiffel Software license template directory.
If you look in the Eiffel Software license template directory (or in the image of that directory shown above), you will see several standard license files that are used by Eiffel Software, for example, forum2.lic and eiffelsoftware. Also included is default.lic, which we'll examine later.
You should create your customized license text files in the Eiffel user files license template directory, or in a local project directory as described below.
If you use the same license for a particular project, or set of related projects, you can keep the license file in the project directory along with your project ( .ecf ) file. In this case EiffelStudio will include the license text from that license file in each class in the project.
This method has the advantage that it is not necessary to put the license_name term in the source code of classes.
The license text file should be named in one of two ways:
.lic file name corresponds to the project name (e.g., my_project.lic for my_project.ecf)
license.lic
The second option is convenient if you have a project, a library for instance, that has multiple .ecf files for different purposes.
Even if the license text you want to use is in one of the license template directories, you can use this local method to retrieve that text without including a license_name term in the source code for each class. You do this by building a local license text file and include in it only a reference to the appropriate license name.
For example, suppose that the our license text is in the file OurLicense.lic in the Eiffel user files license template directory. To include the license text in the classes of our_project, the our_project.lic (or license.lic) file would contain this reference:
reference:OurLicense
As mentioned earlier, the file default.lic exists in the Eiffel Software license template directory. This file is empty ... and you should probably leave it that way.
The license text in default.lic is added to a class when no license_name term is found in the source code and no appropriate license text file exists in the project directory. So, because the default.lic file is empty, no license text is added to classes by default.
However, if you would like to set up a different default license text behavior, you can do so. Just create a default.lic file in the Eiffel user files license template directory, and whenever license text is not found by some other method, the text from your customized default.lic will be included.
So far we have relied on the compiling capabilities of EiffelStudio without exploring them in any detail. We must now understand the principles behind EiffelStudio's compiling strategy, in particular how it reconciles fast turnaround, efficient generated code, and strong typing.
Contents
|
Any speed issue aside, the most important property of the compilation process is that it is entirely automatic.
You've seen it from the beginning of this Tour: all the information the compiler has -- obtained from a configuration file, as here, or generated automatically by the other options -- is the name of the root class and the list of directories holding Eiffel clusters. In fact it only needs these directories for non-precompiled clusters; here, because we are using precompiled EiffelBase, and because we've started EiffelStudio from the Tour's own root cluster directory, EiffelStudio has all the information it needs.
The compiler takes care of finding all the classes that must be compiled.
There is never any need, when compiling Eiffel systems, to supply "Make files", "include files", or other manual descriptions of inter-module dependencies.
EiffelStudio offers several forms of compilation, which you can see in the entries of the Compile menu (don't trigger any of them right now) as well as keyboard shortcuts and, in some cases, buttons:
Project menu and through Tools --> Precompilation wizard), to process an entire library, on which many systems can then rely without having to compile it.
You'll quickly learn to use each of these modes to suit your needs.
EiffelStudio's Melting Ice Technology reconciles the following goals:
The idea of the melting ice is based on the observation that, for the practicing software developer, the crucial day-to-day compilation problem is not how to process an entire system but how best to process a changed system, of which an earlier state had previously been processed.
The change may be big or small; the system may be big or small. ("Small system" here means up to a few tens of thousands of lines.) This gives four possible cases, of which only one is really critical:
| Small System | Large System | |
| Small Change | xxx | |
| Big Change |
If the system is small, as in both of the left column entries, speed of recompilation with a good compiler will be acceptable.
In the bottom-right box, the developers have spent days or weeks changing many classes in a large system, so they will not resent having to wait a little to see the results of the recompilation, as long as the time remains reasonable. In EiffelStudio this corresponds, as we'll see shortly, to finalization, which is in fact fairly fast anyway, but not as fast as the incremental modes.
In the day-to-day, minute-by-minute practice of building and modifying software, the case that recurs by far the most often -- and can cause most frustration -- is the one marked xxx: you change only a small share of a big system. Then the result should come quickly enough. More precisely:
Definition -- Melting Ice Principle: The time to re-process a system after a change should be a function of the logical size of the change, not of the size of the system.
The "logical size" of a change may be different from its physical size because a small physical change in a class may have consequences in many others. Imagine for example that you add a feature to class ANY, although this is an extreme case and won't normally happen. Since every class is a descendant of ANY, the logical change may affect the entire system.
In practice, however, most small physical changes will also be small logical changes and will only cause minimal recompilation. In particular, EiffelStudio will detect that a change does not affect the interface of a class -- for example if it's only a change to non-exported features -- avoiding the need to re-process its clients.
Processing such incremental changes, in time proportional to the logical size of the changes, is known in EiffelStudio as melting. The reason for this terminology is the metaphor illustrated on the following figure. Think of a compiled system as a block of ice; it may have taken some time to "freeze" -- compile. Now you start working on it again; the changes are like melted drops of water, dripping from the ice as a result of the heat generated by your work.
The Melting Ice Technology ensures that incremental compilation will only process the "melted" part, usually small, leaving alone the "frozen" part, which may be large. This is crucial to the incrementality of the mechanism.
The roles of the four compilation modes follow from this analysis:
The following table summarizes the differences between the four compilation modes:
| Regenerate C Code? | Incremental? | Compilation result shared between projects? | |
| Melt | No | Yes (fast) | No |
| Freeze | Yes | Yes (but requires C compilation of changes and linking) | No |
| Finalize | Yes | No | No |
| Precompile
| Yes | No | Yes |
During the production and modification of your software, you will usually alternate between melting and freezing, since both of these modes are incremental. Most of the time, you will simply melt, since melting satisfies the Melting Ice Principle: the time to get back to a working system is very short -- proportional to the size of the changes. Note in particular that the unit of melting is the smallest possible one: each feature of a class -- attribute or routine -- may be melted separately.
The main difference between melting and freezing is that freezing implies re-generating C code for the changed elements, and hence relinking the system as well. In contrast, when you melt changes, you do not change any C code: it remains frozen.
As a consequence, melting can only process changes to Eiffel code. If you add new external code (in C, C++ or other languages whose modules will require linking), you must freeze. This is also true if you add new Eiffel agents. If you ask for a Melt in such cases, the operation will trigger a freeze anyway. More generally, the Compile button, which you have used a number of times to recompile the system in this Tour, triggers a Melt by default, and a Freeze when it has to.
EiffelStudio knows how to hide the differences and present you with a uniform view of the frozen parts (the C code) and the melted parts. Here indeed is the full view of the picture that was previously given in part:
When you examine a component of the system -- to edit a class, produce a view such as Contract or Interface, enable a breakpoint on a routine, run the system, inspect a run-time object -- EiffelStudio automatically knows where to look for the corresponding information: melted or frozen part. If one of your actions requires melting or freezing more elements, EiffelStudio will also handle this automatically.
As suggested by the lower red arrow, successive melting operations "pour water into the bowl", corresponding to the elements that you have changed since the last freeze. Freezing, represented by the top red arrow, updates the C code so that it integrates all the latest changes, emptying the bowl in the process.
Because the difference between melted and frozen code is largely invisible to users of the environment, the term workbench code will cover both kinds; workbench code is code resulting from a succession of freezing and melting operations. As long as you are working within EiffelStudio, you are using workbench code.
When you are happy with the results of your development, you will normally finalize the system, thereby generating final code. Although not strictly required, this step is in most cases appropriate since final code is significantly more efficient than workbench code in both time and space: finalization performs a number of optimizations -- dead code removal, replacement of dynamic by static binding -- that wouldn't be justified in incremental development where, for example, some code element that is "dead" one minute may be resurrected the next moment through the addition of just one line of text. In addition, because finalized code is more efficient than frozen code, it is the natural choice if, using EiffelStudio for cross-platform development, you wish to port the resulting C-package to other architectures.
If you have a set of reusable classes that may be useful to many applications, you can precompile them into a library. This set of classes must be self-contained in the sense that all the classes needed by any of them must be either in the library itself or in another library that you will include in the precompilation.
The result of melting operations -- the contents of the "bowl" -- is an internal software representation known as melted code or (for no particularly good reason) as bytecode. EiffelStudio generated bytecode serves two complementary purposes:
Internally, the melted code is in a file simple.melted (where simple is our project's name) in the subdirectory EIFGENs/simple/W_CODE of the project directory. The file is not human-readable, but as you add elements to your software and melt you watch its size grow. Whenever you freeze, it's emptied.
Note: For systems targeted to Microsoft .Net, bytecode is replaced by that platform's own internal code, MSIL.
You can now see the reason behind the terminology used to describe compilation steps, called degrees on the messages that flash on the screen when you do a compilation. The names are inspired by the international temperature scale -- Celsius, also known as centigrade -- where water freezes at 0 (and boils at 100, but Eiffel software never reaches that). For EiffelStudio:
When should you melt, freeze, finalize or precompile? The answers are simple and follow directly from the preceding overview; they provide the key to getting the environment to work for you in the most effective way possible.
Melting is the bread and butter of the Eiffel developer. As you build your software, either from scratch or by modifying an existing system, you will regularly melt to benefit from the various checks that compilation performs and, of course, to generate executable code that you can test and debug immediately. During this process, there is no need to refreeze, since this operation (although still incremental) takes significantly more time than melting.
Only two operations, noted above, require freezing: the addition of external (non-Eiffel) routines, such as C functions or C++ classes, and the addition of agents. The reason is easy to understand: the EiffelStudio compiler knows how to melt Eiffel software, but not software written in C or other languages; agents similarly require special code generation.
For the first compilation of a system that does not use precompiled EiffelBase, a Freeze is needed since class ANY, from which all other classes inherit, uses some external routines. In this case the environment automatically starts a freeze even if you just click Melt. This does not apply if you have access to precompiled EiffelBase.
Except for the addition of external routines or agents, freezing is never strictly necessary. It is indeed possible to use melting throughout a development, never requesting a freeze after the first compilation. But as the melted-to-frozen ratio grows, you may detect a certain degradation in the performance of the system (determined by how big a share of your system is melted, not how many times you melt it). After a while, then, you may want to refreeze. Like melting, freezing is incremental: only those parts of a system that have been logically changed will be recompiled; as with melting, the determination of what needs to be recompiled is entirely performed by the environment, without any manual intervention on the developer's part.
The principal difference is that freezing takes longer than melting. Because of this you are requested to confirm the first time you freeze. Freeze the example system by choosing the menu entry
Project --> Freeze
Note the No option: by default, freezing will start a C compilation, but you can stop after C generation if you wish. This is useful for example if you want to generate a C package for cross-development, C-compiling the result on a different platform.
Click Yes to confirm freeze and C-compilation. Once the Eiffel compilation is complete, a message in the Development Window ( C compilation launched in background) tells you when that C-compilation has started. C-compilation does not block EiffelStudio: at this point you can continue working with the environment. Any messages from C compiler will appear in the External compilation pane of the Outputs tool.
You will be able to execute the frozen system as soon as the C compilation finishes.
You will note that freezing, although it takes more time than melting, is actually quite fast, both due to the speed of Eiffel compilation and to the structure of the generated C code, designed to optimize the operation of the C compiler.
Note: When you freeze a system targeted to Microsoft .NET, the external compilation of your system is not necessary. The intermediate language generated by EiffelStudio and other .Net compatible compilers will be converted to machine code at runtime by .Net's just-in-time (JIT) translator.
The main reason for finalizing a system is run-time performance of the generated system. Finalization enables you to generate the high-performance executables that are among the hallmarks of ISE Eiffel. As a consequence, finalized code is the best vehicle for cross-development: you can port the resulting C package to various target platforms and C-compile them on these platforms.
The optimizations performed by finalization affect both space and time:
As long as you continue changing, melting and freezing your system, the workbench compiling mechanisms cannot perform such optimizations: if a routine is "dead" today you may resurrect it tomorrow by adding a new call to it somewhere; and if a call is non-polymorphic a single additional assignment may require dynamic binding. Compilation can only generate optimal code by working on a full, stable system. This is the task of finalization.
Cross-development, the second reason for finalizing, is important if you are taking advantage of the portability of ISE Eiffel to develop your system on a certain platform and then run the result on target computers with possibly different architectures. A target machine may lack an ISE Eiffel compiler (unmistakably signaling its owner's backwardness) but include a C compiler. If the development and target platforms are of different architectures you will need to obtain a copy of the run-time system for the target architecture. The run-time system is also ANSI-C-based, so porting it is usually a straightforward matter.
Note that cross-development does not require finalization, since you can cross-compile a frozen version. In practice, however, the finalized version is usually the preferred form for porting a C package because of the performance advantage.
Finalize the example system now by selecting the menu entry
Project --> Finalize
Along with compilation from within EiffelStudio, it is possible to start compilation from a command line (shell). This is useful in particular to recompile your system automatically as part of a script.
Click here to see how to use the command line compiler and the set of supported options.
To complete this study of the compilation process let's see a few more properties of how you can execute an Eiffel system, both in EiffelStudio and as a compiled system that you deliver to its users, who may need to run it without EiffelStudio.
Contents
|
Our example system is very simple and has no need for execution arguments. In more advanced cases you may want to pass values to the execution, such as a numeric parameter or a file name, so that you can have different executions without changing and recompiling the software.
In the Eiffel text, you can access such run-time arguments through the Kernel Library class ARGUMENTS. There is another technique -- using the arguments to the root creation procedure -- but using ARGUMENTS is the most general way. Any class of your system can inherit from ARGUMENTS and use queries argument_count to know the number of arguments passed to the execution, and argument (i), for i between 1 and argument_count to access the i-th element. Class ARGUMENTS has more features; since you have Eiffelstudio up, you can check the details if you wish (use the contract form).
There are 2 ways to specify execution arguments from within EiffelStudio. The first is through the menu path
Project --> Project Settings --> Debug/Profile --> Program Execution
We have seen how to execute a compiled system from within EiffelStudio: choose one of the appropriate execution buttons, with or without breakpoints.
A finalized system can be executed on any computer of the appropriate platform; it doesn't need EiffelStudio. The executable version is in the directory
project_directory/EIFGENs/target_name/F_code
where project_directory is the project's directory and target_name ist the name of the target. The name of the executable file is
system_name.exesystem_name is the name that you have assigned to your system in the project settings (reflected in the ECF file).
The target of the Guided Tour system is classic and the name is simple, so you can locate simple.exe in EIFGENs/classic/F_code for your project, and run it stand-alone if you like.
If you run the system from a command line, and it requires arguments (simple doesn't), you will provide the appropriate arguments after the command name:
system_name.exe ... arg ...
Because various platforms have different conventions, "relative paths" referenced in your system will mean something different under Unix/Linux, where they relate to the directory from which the command is launched, and under Windows, where they relate to the application's directory.
A system compiled in "Workbench mode" -- frozen or melted -- is normally meant for execution within EiffelStudio, not for outside delivery, since it is not optimized. If you need to execute it outside of EiffelStudio, make sure that you have access to the system_name.melted file in project_directory /EIFGENs/target_name/W_code.
With this discussion of compilation and execution we have finished our review of the key capabilities of EiffelStudio. Not everything has been covered, but you are now familiar with the essentials and ready to discover the rest by yourself, both by trying out various capabilities -- most of which should be self-explanatory -- and examining the extensive online documentation that accompanies the product.
This appendix provides reference information, not needed in simple uses of EiffelStudio.
We saw in the section on documentation that you can output documentation about your system in many different formats. A number of predefined formats are available, from Postscript to Microsoft's Rich Text Format, FrameMaker, HTML with and without style sheets, TEX and others. There's nothing special about these formats: they just make their conventions known to EiffelStudio through a filter expressed in a simple notation called EFF, or Eiffel Filter Format. If you have a favorite format that you'd like EiffelStudio to use for producing documentation, you can define your own filter in EFF. Applications include:
This appendix describes EFF and its conventions, enabling you to write filters. Note that in practice the best way to write an EFF filter is usually not from scratch, but by copying an existing filter -- one that seems closest to your needs -- and adapting the copy.
Contents
|
When you choose to generate documentation, EiffelStudio will ask you to select a filter from a list it obtains by looking up the files of extension . fil in the directory
$ISE_EIFFEL/studio/filters
To make a new filter available to yourself and other users of this installation, just add the corresponding file name . fil to this directory. Make sure to choose the appropriate name, since this is what the menu of available filters will display.
An EFF filter follows a very simple structure. As with all other Eiffel-related notations (such as Eiffel itself and Lace, the control language for Eiffel systems), any line or part of a line beginning with two consecutive dashes -- is a comment, except if it immediately follows a percent sign since, as will be seen below, -Â %- is used to denote an Eiffel comment in the class text. Blank lines are also permitted. Comments and blank lines carry no semantic value.
Except for comments and blank lines, a filter is a sequence of entries, all of the form
Construct | Replacement
where: Construct is one of a set of possible strings, most of which correspond to Eiffel constructs such as Class_declaration or Eiffel keywords such as class ; and Replacement is a string indicating how to format specimens of the Construct that appear in a class text.
For readability, there may be any number of blanks or tabs between the Construct and the vertical bar |, so that you can align all the bars if you wish. On the right of the bar, however, all characters including blanks and tabs are significant, since they are part of the replacement for the Construct.
In the Replacement part, you may use the symbol * (asterisk) to denote the construct specimen itself. So for example the entry
Feature_clause |Â %N%N*%N%N
specifies the following formatting for any Feature_clause: two successive blank lines (expressed as %N, New Line, a convention taken from Eiffel); the feature clause itself; two blank lines.
Similarly, in an HTML format, the entry
External |<B> * </B>
means that the Eiffel keyword external must appear in the filtered form immediately preceded by <B>, the HTML code for switching to boldface, and immediately followed by </B>, the code for reverting to the previous setup. Here you can also write the right-hand side without the asterisks, as <B>external</B>. If, however, all keywords are to use boldface, it is preferable to write a single entry
Keyword |<B> * </B>
which, thanks to the asterisk, will govern all construct specimens of the Keyword category. You can still override this specification for an individual keyword by including a specific entry for it.
The following general syntactic constructs may appear as the left-hand side, Construct, of an entry:
Class_declaration Class_end Class_header Class_name Comment Creators Escape Feature_clause Feature_declaration Features Formal_generics Indexing_clause Inheritance Invariant_clause Keyword New_line Obsolete_clause Suffix Symbol Tab
Most of these denote Eiffel constructs as they appear in the official language reference, the book Eiffel: The Language . Since the Eiffel construct names Feature, Invariant and Obsolete are also keywords and EFF, like Eiffel, is case-insensitive, the EFF construct names use the suffix _clause, for example Feature_clause.
The constructs corresponding to syntactic constructs are self-explanatory. The others are:
Class_end, denoting the final end of a class text.
Keyword, denoting any Eiffel keyword among those listed in boldface in the corresponding appendix in Eiffel: The Language
New_line, denoting any passage to a new line in the class text.
Suffix, used to introduce the file extension for the generated documentation files. If you don't specify this, EiffelStudio will use the filter's name as extension.
Symbol, denoting any of the Eiffel symbols listed in the corresponding appendix of Eiffel: The Language .
Escape, to protect special characters of the external tool, as explained below.
Tab, denoting any tab character appearing in the class text.
A Construct part may consist of the name of an Eiffel keyword. To see the complete list of possible keywords, look at the template filter, file format.fil-template in the default filter directory $ISE_EIFFEL/studio/filters, which includes all of them with a single asterisk * as the Replacement part.
If entries are present for both the Keyword construct and individual keywords, the individual keyword entries will override the general entry for the keywords listed; the general entry will apply to all other keywords. This makes it possible to have both a general convention for keywords and a special convention for some of them.
A Construct part may consist of an Eiffel symbol, such as :=, /= and many others. Again, you may see the complete list by looking at format.fil-template. Note the following conventions:
% * represents an asterisk. For example as a multiplication operator; the % avoids the confusion with the special meaning of the asterisk for EFF. You can find examples of this convention in the EFF filters for troff and gtroff.
-Â %-, since just writing - - would introduce a comment in the EFF filter itself.
As with keywords, you may specify a general convention for symbols, defined by an entry for the construct Symbol, and special conventions for certain individual symbols. Specific symbol entries will override the general Symbol convention.
A text processing system or other external tool may attach a special role to characters that may normally appear in Eiffel texts. For example, the braces { and }, used in Eiffel's Export clauses, have a special meaning for TEX. Including them without precaution in TEX input will cause trouble. Similarly, many text processing formats attach a special meaning to the backslash character \ which, although not special for Eiffel, may appear in an Eiffel string.
In such cases the filter must " escape " the special character, that is to say, protect it by other characters. For example troff and other text processing tools treat two successive backslash characters \\ as denoting a single backslash in the text to be output. The first backslash is the escape character, protecting the second one.
The Escape construct addresses such cases. The first character that follows Escape (after one or more blanks or tabs) is the character to be escaped. The string after the vertical bar is the replacement for that character.
Here for example is an escape entry for the backslash in tools that need to escape it through another backslash:
EFF uses Eiffel-like conventions, based on the percent sign, for control characters appearing in Replacement parts of entries. Two of these conventions have just been noted: % * to represent an asterisk and %- to represent a dash that does not introduce an Eiffel comment. In addition:
%| denotes a vertical bar. (This is necessary since EFF uses | by itself in each entry to separate the Construct from the corresponding Replacement.)
%N (recommended form) or %n denotes a new line.
%T (recommended form) or %t denotes a tab.
%% denotes a percent sign.
% (percent followed by a space) denotes a space. This is equivalent to just a space, but more visible.
If c is not one of the characters for which special conventions have been listed, % c denotes the character c itself.
A multi-line entry uses the Eiffel convention for string continuations: % at the end of a line to signal that there is a continuation; a continuation line begins with zero or more spaces and tabs followed by a % ; the characters after the % are the continuation of the string.
Title: EiffelStudio: A Guided Tour, Eiffel Software Technical Report TR-EI-68/GT. (Replaces TR-EI-38/EB.)
Contents
|
First published 1993 as First Steps with EiffelBench (TR-EI-38/EB) and revised as a chapter of Eiffel: The Environment (TR-EI-39/IE), also available as An Object-Oriented Environment (Prentice Hall, 1994, ISBN 0-13-245-507-2.
Version 3.3.8, 1995.
Version 4.1, 1997
This version: July 2001. Corresponds to release 5.0 of the EiffelStudio environment.
Bertrand Meyer
Emmanuel Stapf, Arnaud Pichery, Xavier Rousselot, Raphael Simon; Etienne Amodeo, Jrome Bou Aziz, Vincent Brendel, Gauthier Brillaud, Paul Colin de Verdiere, Jocelyn Fiat, Pascal Freund, Savrak Sar, Patrick Schonbach, Zoran Simic, Jacques Sireude, Tanit Talbi, Emmanuel Texier, Guillaume Wong-So; EiffelVision 2: Leila Ait-Kaci, Sylvain Baron, Sami Kallio, Ian King, Sam O'Connor, Julian Rogers. See also acknowledgments for earlier versions in Eiffel: The Environment(TR-EI-39/IE)
Non-Eiffel Software: special thanks to Thomas Beale, Eric Bezault, Paul Cohen, Paul-Georges Crismer, Michael Gacsaly, Dave Hollenberg, Mark Howard, Randy John, Eirik Mangseth, Glenn Maughan, Jacques Silberstein.
Rich Ayling.
Copyright Interactive Software Engineering Inc. (Eiffel Software), 2001. May not be reproduced in any form (including electronic storage) without the written permission of Eiffel Software. "Eiffel Power" and the Eiffel Power logo are trademarks of Eiffel Software.
All uses of the product documented here are subject to the terms and conditions of the Eiffel Software user license. Any other use or duplication is a violation of the applicable laws on copyright, trade secrets and intellectual property.
Any third-party products mentioned in this document are hereby acknowledged as trademarks of their respective owners.
Degree-granting educational institutions using EiffelStudio teaching purposes as part of the Eiffel University Partnership Program may be permitted under certain conditions to copy specific parts of this book. Contact Eiffel Software for details.
| |
|
Eiffel Software (Interactive Software Engineering) helps you produce software better, faster and cheaper. Eiffel Software provides a wide range of products and services based on object technology, including EiffelStudio, a complete development environment for the full system lifecycle. Eiffel Software's training courses, available worldwide, cover key management and technical topics. Eiffel Software's consultants are available to address your project needs at all levels. Eiffel Software's TOOLS (Technology of Object-Oriented Languages and Systems) conferences, http://www.tools-conferences.com , are the meeting point for anyone interested in the software technologies of the future. Eiffel Software originated one of the earliest .NET products and offers a full range of .NET services and training at http://www.dotnetexperts.com . For more information Eiffel Software maintains a rich source of information at http://www.eiffel.com , with more than 1200 Web pages including online documentation, downloadable files, product descriptions, links to Eiffel Software partners, University Partnership program, mailing list archives, announcements, press coverage, Frequently Asked Questions, Support pages, and much more. Visit http://www.eiffel.com/general/contact_details.html to request information about products and services. To subscribe to the Eiffel Software user list, go tohttp://groups.eiffel.com/join . Support programs Eiffel Software offers a variety of support options tailored to the diverse needs of its customers. See http://support.eiffel.com for details. |
This EiffelStudio reference chapter contains topics with information about many technical aspects of the EiffelStudio product.
Contents
|
PATH was added, and most libraries using a string to represent a file name have been updated to also take a PATH instance as argument.
{ES_OBJECTS_TOOL_PANEL}.real_update.
PATH class to represent a Unicode path. In addition it offers many features to compose or decompose a path in multiple components.
STRING:
STRING_8 or STRING_32 into parent class READABLE_STRING_GENERAL, for example: has, item, index_of, last_index_of, ...
prepend_substring and append_substring for efficient insertion of substrings.
tail and head (which have been obsolete since 2001) with queries creating a copy of the current string with characters removed at the beginning or at the end.
REPEATABLE class.
is_first and is_last queries to iterators.
{MANAGED_POINTER}.copy did not properly set count and thus yielded a postcondition violation when duplicating an instance.
ARGUMENTS_32 class to handle Unicode arguments.
UTF_CONVERTER class to handle various Unicode encoding conversions.
{DEBUG_OUTPUT}.debug_output to be READABLE_STRING_GENERAL, so that Unicode characters in the string representation of an object can be displayed in the EiffelStudio debugger.
incorrect_mismatch' when it was applied to a HASH_TABLE whose keys are expanded but do not have a default value: the retrieved HASH_TABLE had one more item than the original one. It should fix eweasel test#table013.
DECIMAL as an argument of a procedure did not set the scale (thus storing 1.00 when 100.00 was expected).
WEL_FONT for the computation of the size of a string that could cause string access on an invalid index; and removed unused calculations.
WEL_GDIP_METAFILE that would cause a C compilation error when compiled using GCC.
Contents
|
{ARRAY}.force when the new lower index is less than the old lower index - count.
{ARRAY}.force where if the items had to move, the newly allocated area was not reset.
{ARRAY}.force that did not allow storing elements at existing indexes.
{PLATFORM}.is_scoop_capable to find out if a system is compiled using a SCOOP capable runtime.
is_real, is_integer, ...) to class READABLE_STRING_GENERAL to make it easier to handle all the various kinds of strings.
{HASH_TABLE}.disjoint to find out if 2 tables have some common elements or not based on the key comparison criteria.
area' is shared between an ARRAY and an ARRAYED_LIST created via conversion.
copy' for UNIX_FILE_INFO and BOOL_STRING which caused for the former a sharing of some FILE specific information.
{STRING_32}.left_adjust that did not work properly when the string contained only white spaces.
{FILE}.exists on Windows 32-bit when files are larger than 2GB. It only occurs with the latest version of the Microsoft C++ compiler (VS2010 or later).
{DATABASE_MANAGER}.execute_query_without_commit.
{DB_CHANGE}.reset.
THREAD, descendants should now call {THREAD}.make in order to initialize threads properly. This change was required to have a project using SCOOP be able to use libraries that are only aware of multithreading.
WEL_GDIP_METAFILE.
WEL_DISK_SPACE that was not working in 64-bit mode. The fix implies a breaking change in that now a NATURAL_64 is returned instead of an INTEGER_32.
Contents
|
ARRAY in editor, switch to clickable format, try to pick various elements, it would always pick BOOLEAN instead) (bug#17666).
PROCEDURE, FUNCTION, and PREDICATE using a creation instruction. An agent has to be created via the agent expression provided at the language level.
TABLE_ITERATOR and TABLE_ITERATION_CURSOR to provide a common way for TABLE like datastructure to iterate over using the new across loop.
STRING_32 string (previously it was limited to STRING_8).
{FILE}.read_to_string which would not change the hash_code of the string given as argument.
HASH_TABLE lookups.
{POINTER}.is_default_pointer.
BIT_REF from the default setup. In order to use type BIT one has to define a variable USE_BIT.
{LINKED_STACK}.duplicate void-safe, made a postcondition in {INTERVAL}.intersection void-safe.
{ARGUMENT_BASE_PARSER}.copyright deferred.
Contents
|
across) form of the loop construct in clickable views.
ITERATION_CURSOR to simplify crafting cursors for iteration form of a loop on non-container classes, for example, on externally-driven input like files, sockets, etc.
Contents
|
across.
ARRAY:
{ARRAY}.make and {ARRAY}.conservative_resize obsolete as they are not void safe. Alternative recommendation is to use {ARRAY}.make_empty, {ARRAY}.make_filled or {ARRAY}.conservative_resize_with_default.
{ARRAY}.rebase that would help creating an empty array with a given `lower'.
BOUNDED_QUEUE and BOUNDED_STACK have been rewritten to use the same implementation of ARRAYED_QUEUE and ARRAYED_STACK, the only difference is that `extendible' is defined to be False. The `correct_mismatch' feature has been updated to ensure retrieval.
FORMAT_DOUBLE:
FORMAT_DOUBLE where `pad_fraction' did not process properly when one decided to not show the trailing zeros and there were only zeros after the decimal point.
{FORMAT_DOUBLE}.pad_fraction to reflect that the count is set to `decimals' but only when one shows the trailing zeros.
WEAK_REFERENCE to allow weak references in an Eiffel system. This supersedes the IDENTIFIED class which made it necessary to change one's code to allow weak referencing. Currently the class is only implemented for classic Eiffel; it is not available when compiling for .NET.
TRACING_HANDLER and TRACING_SETTING which let you capture some information about the current execution via callbacks.
FIXED_LIST that would reset `capacity' to `count'.
{TYPE}.is_expanded to find out if a type is expanded or not.
Contents
|
across) form of the loop construct.
trim to the RESIZABLE class and its decendants to allow for minimizing the allocated storage.
ARRAYED_QUEUE to avoid using an extra slot that did not keep any value and was used only for implementation purposes.
ARRAY2 so that it can be used in void-safe mode too. Improved ARRAY2 resizing efficiency.
THREAD class thread-safe which prevents using the same object to launch a new thread. Now there is a precondition is_launchable and a status report is_last_launch_successful to help in determining whether a thread was actually launched.
{ARRAY}.force when compiling EiffelNet in void-safe mode.
read_command_list, write_command_list and exception_command_list are now obsolete and should not be used.
Contents
|
No changes in this release.
EQA_TES_SET.on_prepare is now called during default_create, making it simpler to write void-safe tests.
generating_type to return an instance of TYPE rather than an instance of STRING. Existing code should still compile out of the box since we have equipped TYPE with conversions and new features similar to those of STRING. In the few cases where it would still not compile, use `generating_type.out' to ensure that the code will compile fine regardless of the compiler mode chosen (i.e. experimental or non-experimental).
copy from HEAP_PRIORITY_QUEUE which would not do anything because it was simply copying itself, not the other queue.
remove from HEAP_PRIORITY_QUEUE which caused the internal structure to be referenced beyond its bounds.
clear_all in STRING_8, STRING_32 and HASH_TABLE obsolete. One has to use wipe_outinstead.
resize in STRING_8/STRING_32 to forbid values that would shrink the string content. Use grow instead to preserve the former resize behavior.
SEARCH_TABLE which is a HASH_TABLE where keys and items are the same (basically becoming a set), and sorting facilities for INDEXABLE containers.
READABLE_STRING_GENERAL.
{EXECUTION_ENVIRONMENT}.put had no effect on the actual process environment variables because the API was only available in .NET 2.0 which is what we now support at the minimum.
{MEMORY}.memory_map which would cause a precondition violation in one of its call.
{BINARY_SEARCH_TREE_SET}.remove which would not move the cursor and thus causing an infinite loop in subtract and intersect.
{PART_SORTED_SET}.put and {PART_SORTED_SET}.extend which had no effect and thus causing a postcondition violation.
{BOUNDED_QUEUE}.linear_representation.
Contents
|
attribute keyword to create an attribute body.
attached syntax for code completion.
{TABLE}.item from originally put to force. As a consequence, descendants of TABLE might get a VDRD error if redefining item
same_keys to HASH_TABLE. You can redefine this feature to use a different comparison criterion for the keys.
is_equal. As a result, if you had heterogeneous containers, then it might not find items that were found before (although it was a catcall).
alias notation instead of infix/prefix.
shared_substring which will let you create a substring of an existing immutable string without actually duplicating the data.
default_create from CELL has been removed to ensure that the same code can be compiled in both non-void-safe and void-safe mode.
{EXCEPTION}.cause which returns the exception object that caused the current exception while executing the rescue clause.
{EXCEPTIONS}.original* with 5.7 potentially breaking code using exceptions.
{INTERNAL}.set_reference_field to set a reference attribute to Void if the attribute is of a detachable type.
INTERNAL, fixed a bug that would not recognize a class name A_SOMETHING as a valid identifier for INTERNAL.
IO_MEDIUM.last_string to be attached so that existing code can easily be migrated to void-safe without changing the pattern read_line/last_string.
LINKED_LIST and providing the same list as argument would wipe out the content of the LINKED_LIST instead of preserving the elements.
merge_left and merge_right on a TWO_WAY_LIST was violating the invariant.
wipe_out on an ARRAY2 was violating the invariant.
IO_EXCEPTION and RUNTIME_IO_EXCEPTION thus breaking existing code not based on Eiffel exception object.
NETWORK_STREAM_SOCKET.
SOCKET caused by failure to free the temporary buffer used to hold the data.
make_from_fd to make_from_descriptor_and_address.
Contents
|
note keyword and the updated variant keyword location in a loop through the environment.
is keyword is missing.
sleep to EXECUTION_ENVIRONMENT and made sleep from THREAD_CONTROL obsolete.
read_xxx_thread_aware in IO_MEDIUM so that reading a file is not blocking in a multithreaded context.
READABLE_STRING_8/32 and IMMUTABLE_STRING_8/32). Because READABLE_STRING_8 is deferred, some code using expression of the form STRING + SYSTEM_STRING in .NET mode will not compile anymore. Instead one has to do STRING + create {STRING}.make_from_cil (SYSTEM_STRING).
{READABLE_STRING_GENERAL}.same_string to compare any kind of strings together.
TRACING_SETTING class.
{TABLE}.item from put to force a new feature of TABLE. This allows the bracket operator on HASH_TABLE to work properly, that is to say hash_table [i]Â := j will indeed insert 'j' at key 'i' even if key 'i' is already present. Before it was silently doing nothing since it was using put.
SORTED_TWO_WAY_LIST and then modifying the copy by adding an element. This introduces a breaking change in all descendants of SORTED_TWO_WAY_LIST.
Click here to check out what was new in other versions
Contents
|
<Precursor> in your descendant comment to reuse the parent one which is shown in all our formatter tools..
SPECIAL}.same_items and {SPECIAL}.all_default to take an extra argument. Our analysis shows that it was only used by ARRAY and that it should be harmless. If you have a compilation error, simply add `0' as first argument of your call.
physical_size in INTERNAL to return the real allocated size of an object along with its header size.
deep_physical_size in INTERNAL to compute the size of an object and all its dependencies.
read_stream in FILE so that it used underlying `fread' once rather than calling `getc' for each requested character. Our benchmarks show that you can save up to 2s for 1000 calls.
item in ARRAY2. This might break descendant classes of ARRAY2 redefining item.
SOCKET}.read_stream where if there was a socket error, then it would cause a precondition violation in C_STRING.
DEBUG_OUTPUT for DATE, TIME and DATE_TIME objects making it easier to debug code based on them.
WEL_REGISTRY}.enumerate_key where the routine would go in an infinite loop if the key name was larger than 64 characters.
Click here to check out what was new in other versions
Contents
|
BINARY_SEARCH_TREE: Added tree_item which matches the item being searched.
LINEAR: Added item_for_iteration as a synonym of item.
STRING_8 and STRING_32:
to_xxx routines.
starts_with and ends_with.
GC_INFO: Fixed non working computation of CPU time usage on Windows and added two new queries (cpu_total_time and sys_total_time) to find out the total CPU execution time of the program at the last GC cycle.
MEMORY: Added execute_without_collection to execute a procedure with no GC.
Click here to check out what was new in other versions
Contents
|
LINKED_QUEUE.twin which would violate its invariant.
LINEAR_ITERATOR.
REAL_32 and REAL_64 values in big and little endian format in MANAGED_POINTER.
INTERNAL so that it does not have the is_pre_ecma_mapping_disabled attribute. If you were setting it to True, you should instead create an instance of ECMA_INTERNAL (fixes bug#11792).
HASH_TABLE:
HASH_TABLE iteration and lookup by about 8% or more.
TUPLE can now compare items using reference equality (=) or object comparison (is_equal).
SPECIAL.copy_data which was previously not inlined due to a change of signature preventing the inlining.
EXECUTION_ENVIRONMENT.get will only retrieve environment variable. It won't retrieve a value from the registry key on Windows (from HKLM\Software\ISE\Eiffelxx\app_name). This also means that MELT_PATH on Windows cannot be set in registry; this is not really a problem because now you do not need to set it since the W_code knows where to find it.
WEL_GDIP_BITMAP).
Click here to check out what was new in other versions
Contents
|
STRING, STRING_8, STRING_32 and STRING_GENERAL:
STRING_GENERAL, a common ancestor to STRING_8 and STRING_32. It is useful if you want to handle both ASCII and Unicode string. For example this facility is used in EiffelVision2 and WEL.
STRING can be either STRING_8 or STRING_32 depending on your configuration. Default is STRING_8.
is_integer_xx, is_natural_xx, to_integer_xx and to_natural_xx where xx stands for 8, 16, 32 or 64.
is_number_sequence which is semantically identical to the behavior of is_integer in 5.6. Changed behavior of is_integer to check that it fits into a 32-bit integer value.
is_double, is_real, is_real_32, is_real_64 so that the specification allows optional integral part or decimal part, but not both (as per the ECMA specification of a real constant). This fixes the bug where 1.e-4 was not considered a valid floating point value.
is_boolean to match the ELKS specification which says the lower case version of the string should either be true or false.
from_c_substring which would not properly if argument start_pos was greater than 1.
CHARACTER, CHARACTER_8 and CHARACTER_32:
WIDE_CHARACTER and WIDE_CHARACTER_REF; they are replaced by CHARACTER_32 and CHARACTER_32_REF.
REAL_32 and REAL_64:
REAL into REAL_32, and DOUBLE into REAL_64. REAL can be either REAL_32 or REAL_64 depending on your configuration. Default is REAL_32.
rounded_xxx, floor_xxx and ceiling_xxx where xxx is the current floating point type, as the version returning an INTEGER is definitely not precise for large numbers.
read_attributes in SED_INDEPENDENT_DESERIALIZER because we simply forgot to check that between the retrieved system and the stored system, a type has the same number of attributes.
wipe_out in SED_OBJECTS_TABLE' which did not reset last_index. As a consequence if you were doing several storing in a row, then last_index kept being incremented but when retrieving the data it would fail because it would expect last_index to start at 1, not at the last incremented value.
SED_MEDIUM_READER_WRITER encoding so that it can also be used in a networking context. Basically now before sending the data, we first send the number of bytes of the data, and then the data. The old encoding is still available in SED_MEDIUM_READER_WRITER_1.
lock_marking and unlock_marking to use lock and unlock in INTERNAL in a multithreaded context. Currently used by the serialization classes.
IO_MEDIUM:
read_integer_XX, put_integer_XX, last_integer_xx and read_natural_XX, put_natural_XX, last_natural_XX where XX stands for 8, 16, 32, 64.
HASH_TABLE:
replace_key with a key which is not present in the table.
HASH_TABLEs from version 5.4.
HASH_TABLE when you have keys which have a different type.
item from ARRAY2.
ACTIVE_INTEGER_INTERVAL the action sequence will only be called if the range actually changes.
launch from EXECUTION_ENVIRONMENT to not inherit handles on Windows.
list_eiffel3 and table_eiffel3 to the obsolete library.
FILE.read_line to follow the behavior of the feature in classic mode and to treat either single '%N' or a sequence of '%R' and '%N' as an end of line.
POINTER.out produces under .NET a hexadecimal number like in classic mode rather than a decimal number preceded by 0x.
SOCKET read_integer_XX, put_integer_XX, last_integer_xx and read_natural_XX, put_natural_XX, last_natural_XX where XX stands for 8, 16, 32, 64.
put and read in NETWORK_RESOURCE, FTP_PROTOCOL, HTTP_PROTOCOL, FILE_PROTOCOL so that the error checking code is not using socket_ok which might triggers error when there are none.
recipients and header_from in SMTP_PROTOCOL so that you can provide a nice `From' or `To' in the message since they are different from the addresses you have to pass from MAIL FROM and RCPT TO.
bytes_read query. This is useful to detect graceful shutdown of sockets.
STRING or a generic type with STRING in one of the actual generic parameter have been changed to take an argument of type STRING_GENERAL which should not impact you at all, however make sure that if your redefine such a routine, you need to change the signature to STRING_GENERAL, otherwise you may introduce a CATCALL.
STRING have been changed to STRING_32. Because STRING_32 should not be convertible to STRING, it would break a lot of existing code, as a result and only for a transition period, we made STRING_32 convert to STRING. In the next release this conversion will be marked obsolete, and in the release after the next it will be removed.
STRING as one of the actual generic parameter, we changed STRING into STRING_32. Because no automatic conversion can be done in this case, we have introduced for a routine nnnnn following this pattern a new routine nnnnn_8 whose actual generic parameter is still STRING.
WEL_TREE_VIEW:
get_item_rect which was always returning a 0,0,0,0 rect as we were not correctly initializing the rect structure with the pointer to the item.
get_item_text_rect which returns a rect only for the text of the items.
WEL_WINDOWS_ROUTINES:
window_of_item to reduce the number of cases where we might get an exception. This makes debugging easier.
resource_string_id which generated a call on Void target exception.
WEL_TOOL_BAR_BUTTON.
WEL_WINDOW components.
WEL_LIST_VIEW a bug where if the text of the string is too long, it would be displayed but truncated.
title_bar_height in WEL_SYSTEM_METRICS.
WEL_REGISTRY_KEY_VALUE.string_value that might cause assertion violation when a value is an empty string, because a check whether the last character is null was done without checking if string has at least one character.
Click here to check out what was new in other versions
Contents
|
assign.
infix and prefix in editor and different views.
| Old name | New name |
| EIF_REAL_FUNCTION | EIF_REAL_32_FUNCTION |
| EIF_DOUBLE_FUNCTION | EIF_REAL_64_FUNCTION |
| eif_real_function | eif_real_32_function |
| eif_double_function | eif_real_64_function |
| EIF_REAL_TYPE | EIF_REAL_32_TYPE |
| EIF_DOUBLE_TYPE | EIF_REAL_64_TYPE |
| EIF_FN_FLOAT | EIF_FN_REAL_32 |
| EIF_FN_DOUBLE | EIF_FN_REAL_64 |
serialization cluster of EiffelBase.
ARRAY:
subarray to match ELKS specification. It now returns an ARRAY [G] instead of like Current.
has to return True when searching for Void when comparing objects in an array containing a Void element.
clone/copy which were not really duplicating the internal of the array, and therefore enabling aliasing of its content by more than one array.
occurences that returned when called with void argument and object_comparision is true.
is_equal that caused stack overflow when some array item is the array itself and object_comparision is true.
ARRAYED_LIST:
array_valid_index from ARRAYED_LIST. Descendants of ARRAYED_LIST may need to update their inheritance clause. This fixes ability to use put_i_th with indexes that may violate the invariant of ARRAYED_LIST, for example the code below should trigger a precondition and not violate the invariant of ARRAYED_LIST:
list: ARRAYED_LIST [INTEGER] create list.make (5) list.put_i_th (3, 3)
new_filled_list in ARRAYED_LIST. Descendants of ARRAYED_LIST may need to update their inheritance clause.
HASH_TABLE:
merge to HASH_TABLE.
remove will reset found_item when an element is removed.
INTERNAL:
TUPLE types in dynamic_type_from_string.
set_reference_field to ensure validity of reattachement to attributes.
STRING:
infix "+" to match ELKS specification. It now returns like Current instead of STRING.
new_string. Descendants of STRING may need to update their inheritance clause.
replace_substring that might produce incorrect result when argument and target of the call is the same object.
center_justify that would corrupt memory on classic.
character_justify, left_justify,