Fonctions et procédures, derrière ces termes complétement abstraits, ce cachent l'outil ultime pour faciliter la vie du développeur. Elles permettent d'isoler des traitements particuliers, mais aussi et surtout d'éviter de réécrire plusieurs fois le même code de traitement.
Allé hop, on retourne dans le fond de ma cuisine pour vous montrer l'utilité, je veux boire un verre de jus d'orange par exemple, et je vais détailler l'action :
- ouvrir le placard
- prendre un verre
- fermer le placard
- ouvrir le réfrigérateur
- prendre la bouteille de jus d'orange
- fermer le réfrigérateur
- ouvrir la bouteille de jus d'orange
- verser du jus d'orange dans le verre
- fermer la bouteille de jus d'orange
- ouvrir le réfrigérateur
- ranger la bouteille de jus d'orange
- fermer le réfrigérateur
- boire le contenu du verre
cela fait quant même beaucoup d'action à réaliser, juste pour boire un verre de jus d'orange, c'est quant même plus simple de dire, ' je vais boire un verre de jus d'orange' que 'je vais ouvrir le placard, prendre un verre, fermer le placard, ouvrir le réfrigérateur, prendre la bouteille de jus d'orange, fermer le réfrigérateur, ouvrir la bouteille de jus d'orange, verser du jus d'orange dans le verre, fermer la bouteille de jus d'orange, ouvrir le réfrigérateur, prendre la bouteille de jus d'orange, fermer le réfrigérateur, boire le contenu du verre'.
Surtout, si j'aime bien boire du jus d'orange et que j'y retourne 5 fois dans la journée.
Dans un programme, c'est exactement pareil, un traitement peut être isolé dans une fonction ou une procédure, pour permettre d'éclaircir le code et de pouvoir aussi l'utiliser à différents endroits, effectivement, je peux très bien boire du jus d'orange ailleurs que chez moi, bon certes, je vais pas aller me servir dans le réfrigérateur d'un restaurant, il faut aussi savoir qu'il ne faut pas utiliser un même traitement partout, il peut ne pas être forcément adapté.
Je vais modifier mon exemple pour le rendre plus concret du point de vu programmation, je vais donc calculer des surfaces et des perimètres de rectangle
Code |
Programme : Calcul_geometrique Variables : largeur est un entier longueur est un entier perimetre est un entier surface est un entier Début : | largeur <- 5 | longueur <- 9 | | perimetre <- (largeur * 2) + (longueur * 2) | surface <- largeur * longueur | | afficher perimetre | afficher surface | | largeur <- 3 | longueur <- 4 | | perimetre <- (largeur * 2) + (longueur * 2) | surface <- largeur * longueur | | afficher perimetre | afficher surface | | largeur <- 2 | longueur <- 7 | | perimetre <- (largeur * 2) + (longueur * 2) | surface <- largeur * longueur | | afficher perimetre | afficher surface | Fin |
en regardant cet algorythme, on voit tout de suite qu'un bloc est répété plusieurs fois à l'identique :
Code |
| perimetre <- (largeur * 2) + (longueur * 2) | surface <- largeur * longueur | | afficher perimetre | afficher surface |
On va donc en faire une procédure. Mais vous vous demandez pourquoi une procédure et pas une fonction, et quel en est la différence?
La différence est toute bête, la fonction renvoie une valeur, alors que la procédure ne le fait pas. On verra des exemples plus loin.
L'utilité d'une procédure ou d'une fonction, c'est que l'on peut lui passer des paramètres pour pouvoir effectuer des traitements sur des données qui peuvent changer. Dans notre cas, il s'agit de largeur et longueur, voici l'algorythme de la procédure 'calcul_geo_rectangle'
Code |
Procédure : calcul_geo_rectangle Paramètres : ENTREE : largeur est un entier ENTREE : longueur est un entier Variables : perimetre est un entier surface est un entier Début : | perimetre <- (largeur * 2) + (longueur * 2) | surface <- largeur * longueur | | afficher perimetre | afficher surface Fin ________________________________________________ Programme : Calcul_geometrique Variables : Début : | calcul_geo_rectangle(5,9) | | calcul_geo_rectangle(3,4) | | calcul_geo_rectangle(2,7) Fin |
Le programme principal à déjà une meilleur tête, non ?
maintenant, la même chose en Ruby, sans définir de procédure :
(Ruby) | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
largeur = 5
longueur = 9 perimetre = (largeur * 2) + (longueur * 2) surface = largeur * longueur print perimetre print surface largeur = 3 longueur = 4 perimetre = (largeur * 2) + (longueur * 2) surface = largeur * longueur print perimetre print surface largeur = 2 longueur = 7 perimetre = (largeur * 2) + (longueur * 2) surface = largeur * longueur print perimetre print surface |
avec la procédure :
(Ruby) | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
def calcul_geo_rectangle(largeur,longueur)
perimetre = (largeur * 2) + (longueur * 2) surface = largeur * longueur print perimetre print surface end begin calcul_geo_rectangle(5,9) calcul_geo_rectangle(3,4) calcul_geo_rectangle(2,7) end |
Comme vous avez pus le comprendre l'opérateur 'def' en ruby, permet de définir une fonction ou une procédure. Les paramètres qui sont définit dans la ligne définition, récupère automatiquement les valeurs qui sont transmis lors de l'appel. Il est possible de définir des valeurs par défaut :
(Ruby) | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
def calcul_geo_rectangle(largeur = 1,longueur = 1)
perimetre = (largeur * 2) + (longueur * 2) surface = largeur * longueur print perimetre print surface end begin calcul_geo_rectangle(5,9) calcul_geo_rectangle(4) calcul_geo_rectangle end |
Dans le deuxième appel, largeur prendra pour valeur : 4 et longueur : 1
Dans le troisième, largeur : 1 et longueur : 1
Attention, les valeurs par défaut doivent être définit, en commençant par la fin et doivent être contigûes, voici des exemples de ce qu'il NE faut PAS faire :
def ma_procedure(param_A = 2, param_B, param_C)
def ma_procedure(param_A, param_B = 3, param_C)
def ma_procedure(param_A = 2, param_B, param_C = "12")
Maintenant, en ce qui concerne les fonctions, et bien c'est exactement la même chose hormis le fait que l'on revoie une valeur en utilisant l'opérateur 'return'. Un petit exemple rapide juste pour le périmètre.
(Ruby) | |
1 2 3 4 5 6 7 8 |
def perimetre_rect(largeur = 1, longueur = 1)
perimetre = (largeur * 2) + (longueur * 2) return perimetre end begin print (perimetre_rect(3, 5) + perimetre_rect(2, 2) ).to_s end |
Comprenez bien qu'un calcul fait avec une variable de retour d'une fonction est soumis au même règles de typage qu'une variable classique. Si votre fonction retourne une chaine et que vous tentez de faire une division dessus, il se produira une erreur. Soyez donc très vigilant.
Voila, je pense que l'on a bien survolé les bases de la programmation structurelle, des choses on peut être été oublié, mais savoir rechercher une information est la compétence la plus importante d'un informaticien et donc d'un développeur. Il existe de nombreux site de référence proposant des guides des fonctions Ruby.