Difference between revisions of "Libraries"

(Local Swiss Application)
Line 30: Line 30:
  
 
=== Name Clash Example ===
 
=== Name Clash Example ===
==== Library swiss_bank ====
+
==== Swiss_bank library ====
 
Provided by a Swiss bank
 
Provided by a Swiss bank
  
Line 38: Line 38:
 
* EUROCARD
 
* EUROCARD
  
==== Library us_bank ====
+
==== Us_bank library ====
 
Provided by a US bank
 
Provided by a US bank
  
Line 73: Line 73:
  
 
==== International Application ====
 
==== International Application ====
Uses both swiss_bank and us_bank to transfer money from a swiss bank to a us_bank. MONEY and ACCOUNT conflict. To solve the name clash, the user adds a prefix CH_ on the usage of the swiss_bank library and a prefix of US_ on the us_bank library.
+
An international application needs to use both Swiss_bank and Us_bank, for example to transfer money from a Swiss bank to a US bank. MONEY and ACCOUNT conflict. To solve the name clash, the author of the international application adds a prefix CH_ when using Swiss_bank classes and, similarly, a prefix US_ for those of US_bank.
  
 
<code>[eiffel, N]
 
<code>[eiffel, N]
Line 102: Line 102:
 
end
 
end
 
</code>
 
</code>
As the renaming is done on the usage of the library, this does not break the Local Swiss Application. This allows also to have situations where we use a library directly and use another library that in its implementation uses the same library and we may have to do a renaming, then this still works. The idea is that a library can not be "broken" from the outside. A library always works independently of what the usage of the library is.
+
As the renaming is done on the the side of library usage, it does not break any local applications that use only one of the libraries.
 +
 
 +
The scheme also supports an application that uses both a library A and a library B which itself uses A, and some renaming is needed.
 +
 
 +
The idea is that a library can never be "broken" from the outside: it always works independently of existing usage.
  
 
== Implementation ==
 
== Implementation ==
=== UUID ===
+
=== Unique library identifiers ===
To decide if two libraries that are referenced in an application are the same we use a UUID. This solves problems that occur if the same library is referenced with different paths (for example with symlinks). This allows to compile each library only once even if it is referenced multiple times by other libraries. Renamings are handled in a way that renaming/prefixing a library in a library does not effect other libraries or the application itself.
+
To decide if two libraries referenced in an application are the same, the EiffelStudio scheme uses a UUID (unique identifier). Two problems this technique addresses are:
 +
 
 +
* Any error that could result if the same library is referenced through different paths (for example with symbolic links).
 +
 
 +
* Making it possible to compile each library only once even if multiple parts of the applications (including other libraries) refer to it.
 +
 
 +
* Making sure that renaming (prefixing) classes of a library A in a library B does not affect other parts of the application, including other libraries.
 +
 
 +
=== How to perform a renaming ===
 +
Under EiffelStudio, select Project Settings, then Libraries under Groups, and the desired library. Under "Advanced", double-click Renaming; enter the old names (e.g. MONEY) and corresponding new names (e.g. CH_MONEY).

Revision as of 16:17, 26 January 2010

General

What is a library?

A library is a collection of functionality that is exported by an interface. The implementation of the library is not exported so that the library can be changed without affecting users of the library as long as the interface is compatible.

What is in a library?

A library has classes that are available to users and may also have classes that are only in the library for implementation purposes and are therefore not available to the user of the library. A library normally also has dependencies on other libraries and may have externals, pre/post compile tasks and may mark some classes as visible (they will always be compiled). It is also possible to specify several options for the use of a library. E.g. it is possible to disable warnings or set a certain assertion level (see ConfigurationOptions).

Name clashes and conflicts

As libraries are designed and created independently of each other it is possible that two libraries have classes in them which have the same name. As long as the classes with the name clash are only in the implementation part of the library (and therefore not exported) the user of the library does not have to do anything as there is no conflict for him. If the name clash is in the interface part of the two libraries the user of the libraries has to deal with them. There are several possible solutions:

  1. Prefixing: He can prefix one (or both of the libraries) in his system.
  2. Renaming: Renaming is very similar to Prefixing, the only difference is that instead of adding a prefix to all classes, only one (or a few) classes receive a different name.

Testing and Debugging of a library

It is possible to add testing and debugging code to a library by adding additional targets (that inherit from the library target). This targets can then be used to debug and test the library and make the library a fully self contained component.

Examples

EiffelBase

EiffelBase is the most often used library as almost every system and library uses it. Base consists of one recursive cluster which is exported. In .NET mode base also uses some assemblies for its implementation (of which the contents are not exported). Base does not have any externals or dependencies on other libraries.

Graphic

A platform independent graphic library could look something like this: One exported interface cluster that describes the interface of this library. One not exported implementation cluster for each supported platform. For example on windows this implementation could make use of the WEL library and on Macintosh it could do all the implementation directly and may use C externals. There could also be a target that builds a sample application to debug various things of the library. One additional target could also build a system that uses and tests all available graphical elements of the library. The developer of the library can use the addition targets for testing and debugging, the user of the library would not know about them and would also not know about the implementation clusters.

Name Clash Example

Swiss_bank library

Provided by a Swiss bank

Exported classes:

  • MONEY
  • ACCOUNT
  • EUROCARD

Us_bank library

Provided by a US bank

Exported classes:

  • MONEY
  • ACCOUNT
  • CHECK

Local applications (Swiss and US)

The local Swiss application uses only the Swiss_bank library and does not have any conflicts.

class
	ROOT_CLASS
 
create
	make
 
feature
 
	make 
		local
			l_money: MONEY
			l_my_account, l_your_account: ACCOUNT
		do
			create l_your_account
			l_money := l_your_account.withdraw_all
 
			create l_my_account.deposit (l_money)
		end
end

The local US application is similar, using only the US_bank library.

International Application

An international application needs to use both Swiss_bank and Us_bank, for example to transfer money from a Swiss bank to a US bank. MONEY and ACCOUNT conflict. To solve the name clash, the author of the international application adds a prefix CH_ when using Swiss_bank classes and, similarly, a prefix US_ for those of US_bank.

class
	ROOT_CLASS
 
create
	make
 
feature
 
	make 
		local
			l_swiss_money: CH_MONEY
			l_us_money: US_MONEY
			l_swiss_account: CH_ACCOUNT
			l_us_account: US_ACCOUNT
		do
			create l_swiss_account
			l_swiss_money := l_swiss_account.withdraw_all
 
			create l_us_money.make (l_swiss_money.value * exchange_rate)
			create l_us_account.deposit (l_us_money)
		end
 
	exchange_rate: REAL_32 is 0.7975
 
end

As the renaming is done on the the side of library usage, it does not break any local applications that use only one of the libraries.

The scheme also supports an application that uses both a library A and a library B which itself uses A, and some renaming is needed.

The idea is that a library can never be "broken" from the outside: it always works independently of existing usage.

Implementation

Unique library identifiers

To decide if two libraries referenced in an application are the same, the EiffelStudio scheme uses a UUID (unique identifier). Two problems this technique addresses are:

  • Any error that could result if the same library is referenced through different paths (for example with symbolic links).
  • Making it possible to compile each library only once even if multiple parts of the applications (including other libraries) refer to it.
  • Making sure that renaming (prefixing) classes of a library A in a library B does not affect other parts of the application, including other libraries.

How to perform a renaming

Under EiffelStudio, select Project Settings, then Libraries under Groups, and the desired library. Under "Advanced", double-click Renaming; enter the old names (e.g. MONEY) and corresponding new names (e.g. CH_MONEY).