---
title: Cours de programmation séquentielle
subtitle: Modules
author: Orestis Malaspinas
<!-- date: 25 avril 2018 -->
sansfont: Sans Serif
---

# Organisation du code

- Au fur et à mesure du développement séparer son code devient important.
- Il faut **modulariser** le code:
	1. Écrire des foncitons.
	2. Séparer le code en fichiers (modules).
- Aide à organiser le code.
- Aide à maintenir le code.
- Permet de "cacher" le code à l'utilisateur (il n'utilisera que ce que vous voulez qu'il utilise).

# Modules

## Une libraire (`crate`{.rust})

- On peut créer une libraire avec `cargo new malibrairie --lib`.
- Ou alors en créant un fichier `lib.rs` "à côté" du `main.rs` (dans `src/`).
- Pour accéder à ce qui se trouve dans la librairie on devra utiliser

	```{.lang-rust}
	extern crate ma_librairie;
	```

- Et appeler les fonctions, enums, ...

	```{.lang-rust}
	ma_librairie::ma_fct();
	ma_librairie::Mon_enum;
	```

## La définition d'un module

- Dans le fichier `lib.rs` on peut à présent créer un/deux/... modules contenant une fonction

	```{.lang-rust}
	mod mon_module { // on peut même insérer d'autres modules à l'intérieur
		fn ma_fonction() {
			unimplemented!(); // macro très pratique!
		}
	}

	mod mon_autre_module {
		fn ma_fonction() {
			unimplemented!(); // macro très pratique!
		}
	}
	```

- Les fonctions `mon_module::ma_fonction()`{.lang-rust}, `mon_autre_module::ma_fonction()`{.lang-rust} auront une signification (et une fonctionalité différente).

## Fichiers (1/3)

- Avoir tous ses modules dans un fichier: pas pratique.
- On *déclare* les modules dans `src/lib.rs`, on met le contenu dans `src/mon_module.rs`

	```{.lang-rust}
	mod mon_module;

	mod mon_autre_module {
		fn ma_fonction() {
			unimplemented!(); // macro très pratique!
		}
	}
	```

- Équivalent à 

	```{.lang-rust}
	mod mon_module {
		// contenu de src/mon_module.rs
	}

	mod mon_autre_module {
		fn ma_fonction() {
			unimplemented!(); // macro très pratique!
		}
	}
	```

## Fichiers (2/3)

- On peut aller encore plus loin: `src/lib.rs`

	```{.lang-rust}
	mod mon_module {
		fn ma_fonction() {
			unimplemented!(); // macro très pratique!
		}

		mod mon_autre_module {
			fn ma_fonction() { 
				unimplemented!(); // macro très pratique!
			}
		}
	}

	```

- Peut devenir:
	- `src/lib.rs`

		```{.lang-rust}
		mod mon_module;
		```
	- `src/mon_module/mod.rs`

		```{.lang-rust}
		fn ma_fonction() {
			unimplemented!(); // macro très pratique!
		}

		mod mon_autre_module;
		```

	- `src/mon_module/mon_autre_module.rs`

		```{.lang-rust}
		fn ma_fonction() {
			unimplemented!(); // macro très pratique!
		}
		```

## Fichiers (3/3)

- Avec la structure de module suivante

	```{.lang-rust}
	mod mon_module {
		fn ma_fonction() {
			unimplemented!(); // macro très pratique!
		}

		mod mon_autre_module {
			fn ma_fonction() { 
				unimplemented!(); // macro très pratique!
			}
		}
	}

	```

- On accède aux deux `ma_fonction()` avec 
	
	```{.lang-rust}
	mon_module::ma_fonction();
	mon_module::mon_autre_module::ma_fonction();
	```

# Visibilité

## Modules (1/4)

- Structure fichiers:

- `src/lib.rs`

	```{.lang-rust}
	mod mon_module;
	```
- `src/mon_module/mod.rs`

	```{.lang-rust}
	fn ma_fonction() {
		unimplemented!(); // macro très pratique!
	}
	```

- `src/main.rs`

	```{.lang-rust}
	extern crate ma_librairie;

	fn main() {
		ma_librarie::mon_module::ma_fonction();
	}
	```

## Modules (2/4)

- Par défaut les modules sont privés.

```
$ cargo build
   Compiling ma_librairie v0.1.0 ($PATH/ma_librairie)

error[E0603]: module `mon_module` is private
 --> src/main.rs:4:2
  |
4 |     ma_librairie::mon_module::ma_fonction();
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0603`.
error: Could not compile `ma_librairie`.

To learn more, run the command again with --verbose.
```

## Modules (3/4)

- On contrôle la visibilité des modules avec `pub`{.rust}.

- On a joute `pub mon module` dans `src/lib.rs`

	```{.lang-rust}
	pub mod mon_module;
	```

- Par défaut les fonctions sont privées.

	```
	$ cargo build
	   Compiling ma_librairie v0.1.0 ($PATH/ma_librairie)                                                                                                                                    
	error[E0603]: function `ma_fonction` is private
	 --> src/main.rs:4:2
	  |
	4 |     ma_librairie::mon_module::ma_fonction();
	  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

	error: aborting due to previous error

	For more information about this error, try `rustc --explain E0603`.
	error: Could not compile `ma_librairie`.

	To learn more, run the command again with --verbose.
	```



## Modules (4/4)

- On a joute `pub fn ma_fonction()` dans `src/mon_module.rs`

	```
	   Compiling ma_librairie v0.1.0 ($PATH/ma_librairie)                                                                                                                                    
    	Finished dev [unoptimized + debuginfo] target(s) in 1.28s
	```

- Quand plusieurs modules sont imbriqués, les appels sont longs: `ma_librarie::mon_module::ma_fonction();`{.rust}

- Avec `use`{.rust}, on peut se simplifier la vie `src/main.rs`

	```{.lang-rust}
	extern crate ma_librairie;

	use ma_librairie::mon_module::ma_fonction;
	
	fn main() {
		ma_fonction();
	}
	```

- Ou encore avec `*` on peut rendre visible tout le module

	```{.lang-rust}
	extern crate ma_librairie;

	use ma_librairie::mon_module::*;
	
	fn main() {
		ma_fonction();
	}
	```

# Résumé

- Les modules permettent de compartimenter le code.
- Par défaut tout ce qui se trouve dans un module est privé.
- On contrôle la visibilité avec `pub`{.rust}
- Si un item est public il peut être accédé depuis n'importe quel module parent.
- Si un item est privé il n'est accessible que depuis son parent direct et n'importe lequel de ses modules enfants.
- On peut rendre visible des sous-modules, ou des items avec `use`{.rust}.