2005-09-07 11:02:15 +02:00
|
|
|
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
|
|
|
|
<!DOCTYPE html
|
|
|
|
|
PUBLIC "-//ENS/Tuteurs//DTD TML 1//EN"
|
|
|
|
|
"tuteurs://DTD/tml.dtd">
|
|
|
|
|
<html>
|
|
|
|
|
<head>
|
|
|
|
|
<title>Fonctions</title>
|
|
|
|
|
</head>
|
|
|
|
|
<body>
|
|
|
|
|
|
|
|
|
|
<h1>Les fonctions en shell</h1>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Vous savez qu'<strong>un script shell n'est rien d'autre qu'une s<>rie de
|
|
|
|
|
commandes</strong> (si vous ne le savez pas, lisez la page d'<a
|
|
|
|
|
href="script.html">initiation <20> la programmation en shell</a>). Mais
|
|
|
|
|
parfois cela pose des probl<62>mes, car lorsqu'un script devient un peu
|
|
|
|
|
long et surtout lorsqu'il est oblig<69> de se r<>p<EFBFBD>ter, les risques de
|
|
|
|
|
bogues (dysfonctionnements) croissent.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<p>
|
2007-07-17 12:01:59 +02:00
|
|
|
|
L'usage des <strong>fonctions</strong> permet de<64>:
|
2005-09-07 11:02:15 +02:00
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<ol>
|
2007-07-17 12:01:59 +02:00
|
|
|
|
<li> <20>viter ces r<>p<EFBFBD>titions<6E>;</li>
|
|
|
|
|
<li> diminuer les risques de bogues<65>;</li>
|
2005-09-07 11:02:15 +02:00
|
|
|
|
<li> augmenter la lisibilit<69> du script pour un humain.</li>
|
|
|
|
|
</ol>
|
|
|
|
|
|
|
|
|
|
|
2007-07-17 12:01:59 +02:00
|
|
|
|
<h2>Pourquoi des fonctions<6E>?</h2>
|
2005-09-07 11:02:15 +02:00
|
|
|
|
|
|
|
|
|
<h3>Un programme sans fonction</h3>
|
|
|
|
|
|
|
|
|
|
<p>
|
2005-09-08 01:00:03 +02:00
|
|
|
|
Utilisateur de TeX ou <a href="&url.tuteurs;logiciels/latex/">LaTeX</a>
|
|
|
|
|
(ou non), vous voulez effacer r<>guli<6C>rement tous les fichiers
|
2005-09-07 11:02:15 +02:00
|
|
|
|
<code>.aux</code> et <code>.log</code> qui polluent vos r<>pertoires.
|
|
|
|
|
Pour ceux qui ne connaissent pas TeX, sachez que ce sont des fichiers
|
|
|
|
|
construits automatiquement, et que l'on peut recr<63>er facilement <20> partir
|
2007-07-17 12:01:59 +02:00
|
|
|
|
du fichier <code>.tex</code><3E>: les supprimer permet donc de gagner
|
2005-09-07 11:02:15 +02:00
|
|
|
|
de l'espace disque sans dommages.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<p>
|
2007-07-17 12:01:59 +02:00
|
|
|
|
Votre script ressemble donc <20> ceci<63>:
|
2005-09-07 11:02:15 +02:00
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
|
#!/bin/sh
|
|
|
|
|
|
|
|
|
|
# fichier "texcleaner" : efface les fichiers aux et log
|
|
|
|
|
|
|
|
|
|
# Je prends chaque fichier .aux du r<>pertoire courant
|
|
|
|
|
for fichier in *.aux
|
|
|
|
|
do
|
|
|
|
|
# J'affiche son nom et demande confirmation pour l'effacer
|
|
|
|
|
echo "$fichier"
|
2007-07-17 12:01:59 +02:00
|
|
|
|
echo "Voulez-vous vraiment l'effacer<65>? (o/n)"
|
2005-09-07 11:02:15 +02:00
|
|
|
|
|
|
|
|
|
# Je lis la r<>ponse de l'utilisateur
|
|
|
|
|
read reponse
|
|
|
|
|
|
|
|
|
|
# Et s'il dit oui, j'efface
|
|
|
|
|
if [[ $reponse == "o" ]]
|
|
|
|
|
then rm -f $fichier
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
# Je prends chaque fichier .log du r<>pertoire courant
|
|
|
|
|
for fichier in *.log
|
|
|
|
|
do
|
|
|
|
|
# J'affiche son nom et demande confirmation pour l'effacer
|
|
|
|
|
echo "$fichier"
|
2007-07-17 12:01:59 +02:00
|
|
|
|
echo "Voulez-vous vraiment l'effacer<65>? (o/n)"
|
2005-09-07 11:02:15 +02:00
|
|
|
|
|
|
|
|
|
# Je lis la r<>ponse de l'utilisateur
|
|
|
|
|
read reponse
|
|
|
|
|
|
|
|
|
|
# Et s'il dit oui, j'efface
|
|
|
|
|
if [[ $reponse == "o" ]]
|
|
|
|
|
then rm -f $fichier
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Vous venez de terminer ce programme, et vous <20>tes content, car il
|
|
|
|
|
fonctionne comme vous le voulez.
|
|
|
|
|
</p>
|
|
|
|
|
|
2005-09-07 12:03:49 +02:00
|
|
|
|
<div class="encadre">
|
2007-07-17 12:01:59 +02:00
|
|
|
|
Soyons honn<6E>tes<65>: cet exemple est un peu tir<69> par les cheveux, car
|
|
|
|
|
il existe une commande tr<74>s simple pour faire cela<6C>:
|
2005-09-07 12:03:49 +02:00
|
|
|
|
<pre>
|
|
|
|
|
rm -i *.aux *.log
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
Mais ici, cet exemple <em><3E> la limite</em> est l<> pour illustrer d'une
|
|
|
|
|
fa<EFBFBD>on simple l'int<6E>r<EFBFBD>t des fonctions... Disons alors que cet exemple
|
|
|
|
|
permet de donner une version francis<69>e de la commande
|
2007-07-17 12:01:59 +02:00
|
|
|
|
<code>rm<72>-i<>*.aux<75>*.log</code><3E>!
|
2005-09-07 12:03:49 +02:00
|
|
|
|
</div>
|
2005-09-07 11:02:15 +02:00
|
|
|
|
|
|
|
|
|
<h3>Probl<62>mes des programmes sans fonction</h3>
|
|
|
|
|
|
|
|
|
|
<p>
|
2007-07-17 12:01:59 +02:00
|
|
|
|
Ce programme pr<70>sente certains aspects d<>plaisants<74>:
|
2005-09-07 11:02:15 +02:00
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<ol>
|
2007-07-17 12:01:59 +02:00
|
|
|
|
<li> il n'est pas tr<74>s lisible<6C>;</li>
|
2005-09-07 11:02:15 +02:00
|
|
|
|
<li> il comporte des r<>p<EFBFBD>titions relativement longues (une dizaine de
|
2007-07-17 12:01:59 +02:00
|
|
|
|
lignes)<29>;</li>
|
2005-09-07 11:02:15 +02:00
|
|
|
|
<li> si vous voulez changer le moindre d<>tail, vous devrez rechercher <i><3E>
|
|
|
|
|
la main</i> toutes les occurrences de ce que vous voulez changer, ce
|
2007-07-17 12:01:59 +02:00
|
|
|
|
qui<EFBFBD>:
|
2005-09-07 11:02:15 +02:00
|
|
|
|
<ol>
|
2007-07-17 12:01:59 +02:00
|
|
|
|
<li> est <strong>fatigant</strong><3E>;</li>
|
|
|
|
|
<li> est <strong>fastidieux</strong><3E>;</li>
|
|
|
|
|
<li> est, surtout, <strong>tr<74>s peu fiable</strong><3E>: si vous
|
2005-09-07 11:02:15 +02:00
|
|
|
|
oubliez une occurrence ou que vous modifiez un endroit alors qu'il ne le
|
2005-09-08 01:00:03 +02:00
|
|
|
|
fallait pas, les cons<6E>quences peuvent <20>tre graves.</li>
|
2005-09-07 11:02:15 +02:00
|
|
|
|
</ol>
|
|
|
|
|
</li>
|
|
|
|
|
</ol>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Il faudrait, pour pallier ces inconv<6E>nients, trouver un moyen de
|
|
|
|
|
<strong>centraliser les informations destin<69>es <20> <20>tre r<>p<EFBFBD>t<EFBFBD>es, afin que
|
|
|
|
|
l'on puisse s'y r<>f<EFBFBD>rer <20> chaque endroit o<> cela est
|
|
|
|
|
n<EFBFBD>cessaire</strong>. C'est pour cela que les fonctions existent.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h2>D<>finition et appel d'une fonction</h2>
|
|
|
|
|
|
|
|
|
|
<p>
|
2007-07-17 12:01:59 +02:00
|
|
|
|
L'utilisation des fonctions se fait en deux moments<74>:
|
2005-09-07 11:02:15 +02:00
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<ol>
|
2007-07-17 12:01:59 +02:00
|
|
|
|
<li> d'abord, il faut <strong>d<>finir la fonction</strong><3E>: vous
|
2005-09-07 12:03:49 +02:00
|
|
|
|
d<EFBFBD>crivez quelle s<>rie de commandes il faudra ex<65>cuter lorsque l'on
|
2007-07-17 12:01:59 +02:00
|
|
|
|
appellera la fonction<6F>;</li>
|
2005-09-07 11:02:15 +02:00
|
|
|
|
|
|
|
|
|
<li> ensuite, il faut <strong>appeler la fonction</strong> <20> chaque
|
|
|
|
|
endroit que vous voulez.</li>
|
|
|
|
|
</ol>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h3>Analogies avec le monde humain</h3>
|
|
|
|
|
|
|
|
|
|
<p>
|
2007-07-17 12:01:59 +02:00
|
|
|
|
Dans le monde naturel, on peut comparer cela <20> l'horloge parlante<74>:
|
|
|
|
|
celle-ci commence par dire <20><>au quatri<72>me top, il sera neuf heures
|
|
|
|
|
cinquante-deux<75><78>, puis <20><>top... top... top... top.<2E><>
|
2005-09-07 11:02:15 +02:00
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
On pourrait dire que dans un premier temps, l'horloge parlante
|
|
|
|
|
<em>d<>finit une fonction</em>, en assignant un signal (le quatri<72>me top)
|
2007-07-17 12:01:59 +02:00
|
|
|
|
<EFBFBD> ce qu'il signale (il est neuf heures cinquante-deux)<29>; une fois
|
2005-09-07 11:02:15 +02:00
|
|
|
|
cela clairement d<>fini, l'horloge <em><3E>gr<67>ne les quatre
|
2007-07-17 12:01:59 +02:00
|
|
|
|
<EFBFBD><EFBFBD>top<EFBFBD><EFBFBD></em>, et le quatri<72>me renvoie <20> l'<27>nonc<6E> <20><>il est
|
|
|
|
|
neuf heures cinquante-deux<75><78>.
|
2005-09-07 11:02:15 +02:00
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<p>
|
2007-07-17 12:01:59 +02:00
|
|
|
|
En langage naturel, d<>finir une fonction <20>quivaut <20> dire<72>:
|
2005-09-07 11:02:15 +02:00
|
|
|
|
<em>quand je dirai le nom de la fonction, vous l'ex<65>cuterez</em>. C'est
|
2007-07-17 12:01:59 +02:00
|
|
|
|
un acte de langage, comme quand un arbitre dit aux athl<68>tes<65>:
|
|
|
|
|
<EFBFBD><EFBFBD>Go<EFBFBD>!<21><><EFBFBD>; car tous les athl<68>tes savent que le
|
|
|
|
|
signifiant <20><>Go<47>!<21><> (ou le coup de pistolet tir<69> en
|
2005-09-07 11:02:15 +02:00
|
|
|
|
l'air) signifie qu'ils doivent partir (la fonction a <20>t<EFBFBD> d<>finie dans
|
|
|
|
|
le r<>glement officiel de leur sport).
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h3>D<>finir une fonction</h3>
|
|
|
|
|
|
2007-07-17 12:01:59 +02:00
|
|
|
|
<h4>Comment d<>finir les fonctions<6E>?</h4>
|
2005-09-07 11:02:15 +02:00
|
|
|
|
|
|
|
|
|
<p>
|
2007-07-17 12:01:59 +02:00
|
|
|
|
D<EFBFBD>finir une fonction est extr<74>mement simple<6C>:
|
2005-09-07 11:02:15 +02:00
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
|
nom () {
|
|
|
|
|
instruction1
|
|
|
|
|
instruction2
|
|
|
|
|
...
|
|
|
|
|
}
|
|
|
|
|
</pre>
|
|
|
|
|
|
2005-09-08 01:00:03 +02:00
|
|
|
|
<ol>
|
|
|
|
|
<li>
|
2005-09-07 11:02:15 +02:00
|
|
|
|
On commence par <strong>trouver un nom <20> la fonction</strong>. Vous
|
2005-09-08 01:00:03 +02:00
|
|
|
|
pouvez choisir ce nom <20> votre guise, par exemple
|
|
|
|
|
<code>liste_des_fichiers</code>, <code>effacer_fichier</code>, etc. Il
|
2007-07-17 12:01:59 +02:00
|
|
|
|
est toutefois fortement recommand<6E><64>:
|
2005-09-07 11:02:15 +02:00
|
|
|
|
|
|
|
|
|
<ul>
|
|
|
|
|
<li> de <strong>ne pas donner <20> ses fonctions des noms de commandes
|
|
|
|
|
existant d<>j<EFBFBD></strong>, par exemple <code>ls</code>, <code>mutt</code>,
|
|
|
|
|
etc. Cela pourrait en effet poser de graves probl<62>mes, car les fonctions
|
|
|
|
|
d<EFBFBD>finies dans un programme sont prioritaires sur les commandes integr<67>es
|
|
|
|
|
du shell (<code>cd</code>, <code>alias</code>, etc.) et les commandes
|
|
|
|
|
externes (<code>mutt</code>, <code>mozilla</code>, etc.). Le
|
|
|
|
|
comportement devient difficilement pr<70>visible, et surtout, le script
|
2005-09-08 01:00:03 +02:00
|
|
|
|
sera tr<74>s difficile <20> d<>buguer... </li>
|
2005-09-07 11:02:15 +02:00
|
|
|
|
|
|
|
|
|
<li> de <strong>ne pas utiliser de signes de ponctuation, d'espaces ni
|
2007-07-17 12:01:59 +02:00
|
|
|
|
de caract<63>res accentu<74>s</strong> dans les noms de fonction<6F>;</li>
|
2005-09-07 11:02:15 +02:00
|
|
|
|
</ul>
|
|
|
|
|
|
2005-09-08 01:00:03 +02:00
|
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
<li>
|
|
|
|
|
une fois que vous avez donn<6E> un nom <20> la fonction, notez des
|
2007-07-17 12:01:59 +02:00
|
|
|
|
<strong>parenth<74>ses ouvrante et fermante</strong><3E>: ce sont elles
|
2005-09-07 11:02:15 +02:00
|
|
|
|
qui indiquent <20> l'interpr<70>teur du script qu'il s'agit d'une d<>finition
|
2007-07-17 12:01:59 +02:00
|
|
|
|
de fonction<6F>;
|
2005-09-08 01:00:03 +02:00
|
|
|
|
</li>
|
2005-09-07 11:02:15 +02:00
|
|
|
|
|
2005-09-08 01:00:03 +02:00
|
|
|
|
<li>
|
|
|
|
|
enfin, <strong>entre accolades</strong>, notez la <strong>s<>rie des
|
2005-09-07 11:02:15 +02:00
|
|
|
|
instructions</strong> qu'il faudra ex<65>cuter <20> chaque appel de la
|
|
|
|
|
fonction.
|
2005-09-08 01:00:03 +02:00
|
|
|
|
</li>
|
|
|
|
|
</ol>
|
2005-09-07 11:02:15 +02:00
|
|
|
|
|
|
|
|
|
|
2007-07-17 12:01:59 +02:00
|
|
|
|
<h4>O<> d<>finir les fonctions<6E>?</h4>
|
2005-09-07 11:02:15 +02:00
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Comme l'interpr<70>teur de scripts shell lit des scripts ligne <20> ligne,
|
|
|
|
|
<strong>il faut que la fonction soit d<>finie avant d'<27>tre
|
2007-07-17 12:01:59 +02:00
|
|
|
|
appel<EFBFBD>e</strong>. Sinon, vous recevez un message de type<70>:
|
|
|
|
|
<EFBFBD><EFBFBD>Command not found<6E><64> (commande introuvable). Par convention,
|
2005-09-07 11:02:15 +02:00
|
|
|
|
il est pr<70>f<EFBFBD>rable de <strong>placer <em>toutes</em> les d<>finitions de
|
|
|
|
|
fonction vers le d<>but du programme</strong>, avant toutes les
|
|
|
|
|
instructions.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h3>Appeler une fonction</h3>
|
|
|
|
|
|
|
|
|
|
<p>
|
2007-07-17 12:01:59 +02:00
|
|
|
|
Notre programme sera donc consid<69>rablement all<6C>g<EFBFBD><67>:
|
2005-09-07 11:02:15 +02:00
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
|
#!/bin/sh
|
|
|
|
|
|
|
|
|
|
# fichier "texcleaner" : efface les fichiers aux et log
|
|
|
|
|
|
|
|
|
|
# Je d<>finis ma fonction effacer_fichier
|
|
|
|
|
|
|
|
|
|
effacer_fichier () {
|
|
|
|
|
# J'affiche son nom et demande confirmation pour l'effacer
|
|
|
|
|
echo "$1"
|
2007-07-17 12:01:59 +02:00
|
|
|
|
echo "Voulez-vous vraiment l'effacer<65>? (o/n)"
|
2005-09-07 11:02:15 +02:00
|
|
|
|
|
|
|
|
|
# Je lis la r<>ponse de l'utilisateur
|
|
|
|
|
read reponse
|
|
|
|
|
|
|
|
|
|
# Et s'il dit oui, j'efface
|
|
|
|
|
if [[ $reponse == "o" ]]
|
|
|
|
|
then rm -f $1
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Je prends chaque fichier .aux du r<>pertoire courant
|
|
|
|
|
for fichier in *.aux
|
|
|
|
|
do
|
|
|
|
|
# J'appelle la fonction effacer_fichier pour chaque fichier
|
|
|
|
|
effacer_fichier $fichier
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
# Je prends chaque fichier .log du r<>pertoire courant
|
|
|
|
|
for fichier in *.log
|
|
|
|
|
do
|
|
|
|
|
# J'appelle la fonction effacer_fichier pour chaque fichier
|
|
|
|
|
effacer_fichier $fichier
|
|
|
|
|
done
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
On <20>conomise une dizaine de lignes, on gagne en lisibilit<69>, et les
|
|
|
|
|
risques de bogues diminuent consid<69>rablement car s'il y a des
|
|
|
|
|
corrections <20> apporter, c'est <20> un seul endroit du script, et non d'une
|
|
|
|
|
fa<EFBFBD>on diss<73>min<69>e sur l'ensemble du programme.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Un d<>tail de la fonction <code>effacer_fichier</code> peut vous
|
2007-07-17 12:01:59 +02:00
|
|
|
|
<EFBFBD>tonner<EFBFBD>: nous utilisons l'argument <code>$1</code>. Comme vous le
|
2007-03-25 19:31:36 +02:00
|
|
|
|
savez sans doute (sinon, lisez la page sur
|
|
|
|
|
les <a href="commande.html">commandes shell et leurs
|
|
|
|
|
arguments</a>), <code>$1</code> d<>signe le premier argument pass<73> <20> une
|
2007-07-17 12:01:59 +02:00
|
|
|
|
commande<EFBFBD>; or <strong>les fonctions peuvent recevoir des
|
2007-03-25 19:31:36 +02:00
|
|
|
|
arguments</strong>, exactement de la m<>me fa<66>on que les commandes. C'est
|
|
|
|
|
m<EFBFBD>me tout <20> fait normal, car <strong>les fonctions sont en fait des
|
|
|
|
|
commandes comme les autres, <20> ceci pr<70>s qu'elles ne sont valables qu'<27>
|
|
|
|
|
l'<27>chelle d'un script</strong>, et non <20> celle d'un syst<73>me tout entier.
|
2005-09-07 11:02:15 +02:00
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h3>Les appels entre fonctions</h3>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Sachez enfin que <strong>des fonctions peuvent appeler d'autres
|
|
|
|
|
fonctions</strong>, ce qui donne une extr<74>me souplesse <20> leur
|
|
|
|
|
utilisation.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<p>
|
2007-07-17 12:01:59 +02:00
|
|
|
|
En voici un bref exemple<6C>:
|
2005-09-07 11:02:15 +02:00
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
|
#!/bin/sh
|
|
|
|
|
|
|
|
|
|
# Je d<>finis une premi<6D>re fonction
|
|
|
|
|
|
|
|
|
|
ecrire_sur_une_ligne () {
|
|
|
|
|
echo -n $*
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Je d<>finis une deuxi<78>me fonction qui appelle la premi<6D>re
|
|
|
|
|
|
|
|
|
|
saluer_utilisateur () {
|
|
|
|
|
ecrire_sur_une_ligne "Bonjour "
|
|
|
|
|
echo $USER
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# J'appelle la deuxi<78>me fonction
|
|
|
|
|
saluer_utilisateur
|
|
|
|
|
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h2>Abusez des fonctions</h2>
|
|
|
|
|
|
|
|
|
|
<p>
|
2007-07-17 12:01:59 +02:00
|
|
|
|
De l<>, passons <20> un conseil de programmation<6F>: <strong>abusez des
|
|
|
|
|
fonctions<EFBFBD>!</strong> N'h<>sitez pas <20> cr<63>er des fonctions pour tout
|
|
|
|
|
et n'importe quoi. Vous en tirerez<65>:
|
2005-09-07 11:02:15 +02:00
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<ol>
|
2007-07-17 12:01:59 +02:00
|
|
|
|
<li> un gain de lisibilit<69><74>;</li>
|
|
|
|
|
<li> un gain d'efficacit<69><74>;</li>
|
2005-09-07 11:02:15 +02:00
|
|
|
|
<li> un gain de souplesse.</li>
|
|
|
|
|
</ol>
|
|
|
|
|
|
|
|
|
|
<h3>Gain de lisibilit<69></h3>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
<strong>Un programme sans fonction n'est lisible que s'il est tr<74>s
|
2007-07-17 12:01:59 +02:00
|
|
|
|
petit</strong><3E>: une vingtaine de lignes tout au plus. D<>s qu'un
|
2005-09-07 11:02:15 +02:00
|
|
|
|
programme d<>passe cette taille, il cesse d'<27>tre intelligible d'un seul
|
|
|
|
|
coup d'œil pour un humain.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<p>
|
2007-07-17 12:01:59 +02:00
|
|
|
|
Supposons qu'un programme soit amen<65> <20> r<>p<EFBFBD>ter <em>n</em><3E>fois un
|
|
|
|
|
m<EFBFBD>me fragment de code comportant <em>p</em><3E>lignes<65>; en
|
2005-09-07 11:02:15 +02:00
|
|
|
|
utilisant des fonctions on <20>conomise
|
2007-07-17 12:01:59 +02:00
|
|
|
|
(<em>n</em><3E>-<2D>1)<29>x<EFBFBD><em>p</em><3E> lignes (toutes
|
2005-09-07 11:02:15 +02:00
|
|
|
|
les occurrences de la r<>p<EFBFBD>tition, moins la d<>finition de la fonction).
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
Ce gain de lignes est indissociable d'un gain de lisibilit<69>, car les
|
|
|
|
|
r<EFBFBD>p<EFBFBD>titions fatiguent inutilement le cerveau humain.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h3>Gain d'efficacit<69></h3>
|
|
|
|
|
|
|
|
|
|
<p>
|
2007-07-17 12:01:59 +02:00
|
|
|
|
En recopiant <20><><EFBFBD> la main<69><6E> des fragments identiques de codes,
|
2005-09-07 11:02:15 +02:00
|
|
|
|
vous risquez toujours la faute de frappe. Or, la moindre coquille peut
|
2007-07-17 12:01:59 +02:00
|
|
|
|
avoir des cons<6E>quences, au mieux, impr<70>visibles<65>; au pire,
|
2005-09-07 11:02:15 +02:00
|
|
|
|
catastrophiques.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
En isolant les s<>ries d'instructions dans des d<>finitions de fonctions,
|
|
|
|
|
vous concentrez en un seul endroit la situation possible d'un bogue
|
|
|
|
|
donn<EFBFBD>. Vous pouvez <em>circonscrire le bogue</em>.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<h3>Gain de souplesse</h3>
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
En utilisant des fonctions, vous donnez <20> vos programmes une grande
|
|
|
|
|
souplesse. Si vous voulez apporter une modification d'ensemble <20> un
|
|
|
|
|
programme, vous n'avez plus <20> corriger autant de morceaux du script
|
2007-07-17 12:01:59 +02:00
|
|
|
|
qu'il y a d'occurrences du m<>me fragment<6E>: vous apportez vos
|
2005-09-07 11:02:15 +02:00
|
|
|
|
modifications de mani<6E>re centralis<69>e.
|
|
|
|
|
</p>
|
|
|
|
|
|
2005-09-07 12:18:58 +02:00
|
|
|
|
<p>
|
|
|
|
|
Pour d<>crire ce ph<70>nom<6F>ne, on parle souvent de
|
|
|
|
|
<strong>modularit<69></strong>, ou encore
|
|
|
|
|
d'<strong>encapsulation</strong>. Il s'agit en effet de privil<69>gier
|
|
|
|
|
l'assemblage simple d'<27>l<EFBFBD>ments simples <20> l'assemblage complexe
|
|
|
|
|
d'<27>l<EFBFBD>ments complexes. Ainsi, chaque fonction <em>cache</em> aux
|
|
|
|
|
fonctions qui l'appellent la complexit<69> de son travail, pour leur offrir
|
2007-07-17 12:01:59 +02:00
|
|
|
|
une interface simple<6C>: le travail est divis<69> en autant de petites
|
2005-09-07 12:18:58 +02:00
|
|
|
|
t<EFBFBD>ches que n<>cessaires, au lieu d'une seule t<>che gigantesque et
|
|
|
|
|
labyrinthesque.
|
|
|
|
|
</p>
|
|
|
|
|
|
2005-09-07 11:02:15 +02:00
|
|
|
|
<p>
|
|
|
|
|
Pour toutes ces raisons, n'h<>sitez surtout pas <20> cr<63>er des fonctions et
|
|
|
|
|
<EFBFBD> les embo<62>ter entre elles. La programmation vous para<72>tra de plus en
|
|
|
|
|
plus facile, <20> mesure que vous r<>aliserez des t<>ches de plus en plus
|
|
|
|
|
complexes.
|
|
|
|
|
</p>
|
|
|
|
|
|
2005-09-08 01:00:03 +02:00
|
|
|
|
<p>
|
|
|
|
|
Vous pouvez revenir <20> la <a href="index.html">page centrale sur le
|
|
|
|
|
shell</a>, d'o<> vous pourrez vous orienter vers d'autres parties du
|
|
|
|
|
cours.
|
|
|
|
|
</p>
|
2005-09-07 11:02:15 +02:00
|
|
|
|
|
|
|
|
|
<div class="metainformation">
|
2007-07-17 12:01:59 +02:00
|
|
|
|
Auteur<EFBFBD>: Baptiste M<>l<EFBFBD>s.
|
|
|
|
|
Derni<EFBFBD>re modification le <date value="$Date: 2007-07-17 10:03:42 $" />.
|
2005-09-07 11:02:15 +02:00
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</body>
|
|
|
|
|
</html>
|