Goto

Transcription

Goto
Ceci est un extrait électronique d'une publication de
Diamond Editions :
http://www.ed-diamond.com
Retrouvez sur le site tous les anciens numéros en vente par
correspondance ainsi que les tarifs d'abonnement.
Pour vous tenir au courant de l'actualité du magazine, visitez :
http://www.gnulinuxmag.com
Ainsi que :
http://www.linux-pratique.com
et
http://www.miscmag.com
Ceci est un extrait électronique d'une publication de Diamond Editions
http://www.ed-diamond.com
Creative Commons
Paternité - Pas d'Utilisation Commerciale - Pas de Modification
2.0 France
Vous êtes libres :
•
de reproduire, distribuer et communiquer cette création au public.
Paternité. Vous devez citer le nom de l'auteur original de la
manière indiquée par l'auteur de l'oeuvre ou le titulaire des droits
qui vous confère cette autorisation (mais pas d'une manière qui
suggérerait qu'ils vous soutiennent ou approuvent votre utilisation
de l'oeuvre).
Pas d'Utilisation Commerciale. Vous n'avez pas le droit d'utiliser
cette création à des fins commerciales.
Pas de Modification. Vous n'avez pas le droit de modifier, de
transformer ou d'adapter cette création.
A chaque réutilisation ou distribution de cette création, vous devez
faire apparaître clairement au public les conditions contractuelles de sa mise à
disposition.
• Chacune de ces conditions peut être levée si vous obtenez l'autorisation
du titulaire des droits.
• Rien dans ce contrat ne diminue ou ne restreint le droit moral de l'auteur
ou des auteurs.
Ceci est le Résumé Explicatif du Code Juridique. La version intégrale du contrat
est attachée en fin de document et disponible sur :
http://creativecommons.org/licenses/by-nc-nd/2.0/fr/legalcode
code
Par :: Philippe “BooK” Bruhat :: book@ mongueurs.net ::
:: Jean Forget ::
Goto en Perl
Depuis vos premiers cours de programmation (en C ou
en Pascal), on vous serine de ne pas utiliser goto. Mais
connaissez-vous la raison de cet interdit dogmatique ? Cet
article vous expliquera d’où vient le goto, pourquoi personne
ne l’aime et comment l’utiliser. En Perl.
L’histoire de goto
74
On trouve une commande goto
dans presque tous les langages de
programmation
(FORTRAN,
Algol,
COBOL, SNOBOL, BASIC, C, C++,
Perl...). Le principe de ces commandes est
de faire sauter l’exécution du programme
du point où se trouve le goto au point
indiqué en paramètre. En BASIC, ce sera
un numéro de ligne, mais dans la plupart
des langages (qui n’ont pas de lignes
numérotées) le pointeur de programme
saute à un endroit indiqué par une
étiquette (label en anglais). Le saut dans
un flot d’instructions est une instruction
tellement importante qu’elle existait déjà
à l’âge de la programmation en langage
machine. On la trouve encore dans tous
les microprocesseurs. En assembleur,
le mnémonique correspondant est
généralement JMP (pour jump) ou BRA
(pour branch).
Les GO TO de FORTRAN
En FORTRAN, il existe plusieurs formes de
GO TO : le GO TO classique (unconditional GO
TO), le GO TO calculé (computed GO TO) et
le GO TO assigné (assigned GO TO).


Les explications que je donne dans les
paragraphes suivants sont valables pour
FORTRAN 77. Les programmes d’exemple
ont été testés avec F77, le compilateur
FORTRAN 77 du projet GNU.
GO TO label
Comme prévu, l’instruction GO TO transfère
le contrôle à l’instruction portant l’étiquette
« label ». Pour mémoire, les étiquettes sont
des nombres (situés dans les colonnes
1 à 5), qui doivent être uniques dans le
programme. En guise d’exemple, un petit
programme qui ajoute au total en cours
un entier passé sur l’entrée standard. Le
programme s’arrête quand on lui passe 0
(zéro).
TOTAL=0
10 READ *, I
IF (I.NE.0) THEN
TOTAL=TOTAL+I
PRINT *, TOTAL
GO TO 10
END IF
STOP
END
À l’exécution, on obtient :
$ f77 goto01.f ; ./a.out
1
1.
2
3.
3
6.
4
10.
5
15.
0
Anecdote amusante : en FORTRAN, les
étiquettes n’étant pas des numéros de
ligne, leur ordre n’a aucune importance.
GO TO ( liste ) [,] expression
Le GO TO calculé permet de transférer le
contrôle à l’une des étiquettes d’une liste
en fonction de la valeur de l’expression.
Si l’expression vaut 1 le contrôle est
transféré à la première étiquette de la liste,
à la seconde si elle vaut 2, etc.
Si l’expression ne correspond à la
position d’aucune étiquette, le programme
continuera à l’instruction qui suit le GO TO.
! Exemple de computed GO TO
10 PRINT *, ‘Entrez un entier entre 1 et 8:’
READ *, i
GO TO (100,200,300,400,500,600,700,800) i
PRINT *, ‘Ce nombre ne correspond pas’
GO TO 10 ! redemande un nombre, ad lib.
! Les règles du Perl Club viennent de
! http://www.dave.org.uk/perlclub.html
100 PRINT *, ‘The First Rule of Perl Club’
PRINT *, ‘You do not talk about Perl Club’
GOTO 1000
200 PRINT *, ‘The Second Rule of Perl Club’
PRINT *, ‘You do not talk about Perl Club’
GOTO 1000
300 PRINT *, ‘Third Rule of Perl Club’
PRINT *, ‘A laptop crashes, breaks, runs down. ‘//
&’The hack is over’
GOTO 1000
400 PRINT *, ‘Fourth Rule of Perl Club’
PRINT *, ‘Only two programmers to a pair’
GOTO 1000
500 PRINT *, ‘Fifth Rule of Perl Club’
PRINT *, ‘One bug at a time’
GOTO 1000
600 PRINT *, ‘Sixth Rule of Perl Club’
PRINT *, ‘No Java, no VB’
GOTO 1000
700 PRINT *, ‘Seventh Rule of Perl Club’
PRINT *, ‘Hacks will go on as long as they have to’
GOTO 1000
800 PRINT *, ‘Eighth, and Final Rule of Perl Club’
PRINT *, ‘If this is your first night at Perl Club, ‘//
&’you have to hack’
GOTO 1000
1000 STOP
END
L’exécution du programme donne :
$ f77 goto02.pod ; ./a.out
Entrez un entier entre 1 et 8:
0
Ce nombre ne correspond pas
Entrez un entier entre 1 et 8:
9
Ce nombre ne correspond pas
Entrez un entier entre 1 et 8:
6
Sixth Rule of Perl Club
No Java, no VB
En FORTRAN 95, le computed GO TO
statement est obsolète.
GO TO variable
Le GO TO assigné transfère le contrôle à
l’étiquette contenue dans la variable entière
qui suit. L’étiquette ne peut être affectée à
la variable en question qu’avec l’instruction
ASSIGN (d’où le nom de ce GO TO).
ASSIGN 20 TO I
...
GO TO I
...
20 PRINT *, ‘Etiquette 20!’
Avec cette forme de GO TO, on ne peut
affecter qu’une étiquette à la variable.
Notez qu’on ne peut pas utiliser le = de
l’affectation entière pour stocker l’étiquette
dans la variable.
Goto en Perl
Je ne suis pas assez calé en Fortran pour
pouvoir dire quel est l’intérêt de cette
écriture, sinon pour les effets à distance
qu’elle permet (voir le cas de ALTER en
COBOL, section suivante).
Le cas de COBOL
COBOL se distingue non pas par son GO
TO, mais par son instruction ALTER, qui
permet en quelque sorte d’établir une
déviation. Voici un exemple :
* Début du programme, toutes les déclarations,
* définitions et autres. Verbeux comme c’est
* l’habitude en COBOL
ALTER etiq1 TO GO TO etiq2.
* quelques centaines de lignes de code, également verbeuses
GO TO etiq1.
* encore quelques centaines de lignes
etiq1.
DISPLAY „salut“ UPON CONSOLE.
GO TO suite.
etiq2.
DISPLAY „coucou“ UPON CONSOLE.
GO TO suite.
* et la suite
Comme vous l’avez deviné, ce n’est
pas salut qui s’affichera à l’écran. Mais
l’auriez-vous deviné si j’avais réellement
listé le source complet du programme ?
Cela dit, l’utilisation de ALTER n’est pas
monnaie courante...
à aucun branchement goto donc cette
instruction est vraisemblablement interdite
(il existe des instructions dont le nom
comporte goto, mais il s’agit de déplacer
le pointeur de lecture dans le tampon en
cours d’édition, pas de modifier la position
du pointeur d’instruction). Quant aux
autres variantes de Lisp et aux langages
dérivés, qui n’ont même pas l’excuse
d’être incorporés (embedded) dans un
éditeur de texte, ils ignorent complètement
ce mot et ce concept.
Plus curieux : le langage de
programmation des calculatrices HP-48
ne comporte aucun goto. Pourtant, la
HP-48 est l’héritière de la HP-41 dans
laquelle le goto (orthographié GTO) était
indispensable dès qu’un programme
devait effectuer un traitement itératif. Si
vous grepez la documentation de Ruby
à la recherche d’un GOTO, vous verrez
que c’est un nom ou un prénom assez
répandu au Japon, mais que ce n’est pas
une instruction du langage. En Java, goto
est un mot réservé, mais l’instruction ne
fait pas partie du langage.
Edsger W. Dijkstra
Il existe des langages de programmation
où le goto a été laissé de côté ou, peutêtre, oublié. En voici quelques-uns, que
les auteurs ont utilisés, le plus souvent
de façon éphémère. Vous connaissez le
shell. Vous avez déjà écrit quelques scripts
pour enchaîner quelques commandes qui
reviennent régulièrement. Certains de
vos scripts utilisent même des variables,
des boucles et des tests camouflés en
expressions logiques avec && et || ou des
tests explicites avec if then elif else fi.
Mais aviez-vous remarqué qu’il n’existe
aucune instruction goto ? (Avez-vous au
moins lu la page de man ?).
Un autre langage incontournable pour
quiconque utilise Unix de façon un peu
poussée, c’est AWK. Là aussi, lisez la
page de manuel ou un tutoriel, vous ne
verrez jamais mentionnée d’instruction
goto. Emacs est basé sur le langage Elisp et il comporte donc un interpréteur Elisp incorporé ainsi que la documentation
du langage. Celui des deux coauteurs
qui utilise Emacs pour taper cet article l’a
vérifié, la documentation ne fait référence
Photo Hamilton Richards
Les langages de
programmation sans goto
Edsger Wybe Dijkstra (1930-2002) est un chercheur en
informatique hollandais qui a eu un rôle important dans
le monde de la recherche informatique. Il a travaillé sur
le premier compilateur ALGOL 60 et est l’auteur d’un
algorithme qui porte son nom pour le problème du plus
court chemin (vous pouvez trouvez la description de
l’algorithme de Dijkstra dans l’article « Recherche des
chemins optimaux pour les jeux vidéo » de Fabrice
Rossi dans GNU/Linux Magazine 53).
L’article de 1968 sur goto a eu une
influence considérable : il a accéléré
la disparition du goto des habitudes
de programmation, fait progresser la
notion de « programmation structurée »
et amené la création des structures de
contrôle telles que les boucles while.
La polémique
En 1968, Dijkstra a lancé un pavé dans
la mare, remettant en question l’ordre
établi et proposant de faire table rase du
goto. Dijkstra a publié un papier intitulé
« A case against the goto statement »,
mais que Wirth, alors rédacteur en chef
des « Communications of the ACM » a
changé en courrier au rédacteur en chef,
en lui donnant par la même occasion un
titre destiné à devenir célèbre, « Go To
Statement Considered Harmful ». Dans
cet article, Dijkstra constatait que les goto
nuisent à la compréhension du programme
par un lecteur humain et que la qualité du
code varie en sens inverse de la densité
des goto. Une petite remarque pour ceux
qui voudraient lire cet article : ne vous
attardez pas sur la partie médiane de
l’article, qui décrit un concept d’index
textuel et d’index dynamique. Je doute
fort qu’un quelconque programmeur ait eu
recours à cette méthode pour décortiquer
le fonctionnement d’un programme.
L’essentiel est écrit au début et à la fin
de l’article, le goto est indésirable et il doit
disparaître.
Un peu plus tard, Donald Knuth a publié un
autre article, « Structured Programming
with go to Statements ». Le titre donne
l’impression d’être un pamphlet destiné
à répondre avec véhémence à l’article
de Dijkstra. En lisant l’article, on constate
que ce n’est pas du tout le cas. Knuth le
dit lui-même : il ne prend pas parti dans
la guerre sainte des partisans et des
adversaires du goto. Il veut simplement
raconter comment il programme et
quelle place le goto a dans son code. Il
ajoute que les adversaires du goto liront
des arguments allant dans le sens de
l’éradication du goto et que les partisans
du goto liront des arguments justifiant
l’existence du goto. Et effectivement, à la
lecture de son article, on peut constater
que Knuth aborde le sujet avec un esprit
ouvert et serein, sans idée préconçue et
sans œillères.
L’article de Knuth montre qu’il n’y a pas
besoin d’insérer des goto pour obtenir un
programme illisible. Il montre comment
émuler les goto avec une boucle et une
structure conditionnelle et il fait remarquer
à juste titre que le programme obtenu est
encore moins lisible que le programme
d’origine avec des goto (construction
due à Jacopini). Remarquons que Knuth
75
code
réfute ainsi la partie médiane de l’article
de Dijkstra en montrant que le système
d’index textuels et dynamiques ne permet
pas à un humain de mieux comprendre
le fonctionnement du programme. Les
deux gourous ont tiré des conclusions
différentes, que je présenterai au moyen
d’une métaphore. Pour Dijkstra, puisque
certaines personnes se sont intoxiquées
en ingérant de l’eau de Javel, il faut
interdire totalement la commercialisation
de ce produit et le réserver aux chimistes
professionnels. Pour Knuth, il faut vendre
l’eau de Javel dans des récipients avec
des bouchons de sécurité tels qu’un enfant
de moins de 7 ans ne puisse pas l’ouvrir
et il faut que les parents instruisent leurs
enfants pour leur présenter les dangers de
l’eau de Javel et les précautions d’emploi.
Quand on y réfléchit bien, nous sommes
entourés d’ustensiles et d’engins qui,
mal utilisés, sont dangereux voire létaux
mais qui, dans des conditions normales
d’utilisation, sont inoffensifs ou presque :
couteaux, ciseaux à bouts pointus,
tondeuses, prises électriques, etc. Pour
les programmeurs, il ne faut pas oublier
d’ajouter goto à la liste. ;-)
Le folklore
76
La notoriété de l’article de Dijkstra a
eu un effet secondaire, l’expression
« considered harmful» qui, comme nous
l’avons vu, n’est pas due à Dijkstra mais
à Wirth, a été reprise à maintes reprises
et est finalement passée dans le langage
courant (des informaticiens, s’entend).
Si vous googlez cette expression, vous
obtenez 65 000 pages, dont plus de 6 000
si vous restreignez la recherche aux titres.
Dans deux cas, les auteurs ont voulu
élever le débat au niveau supérieur, avec
« ‘Goto statement considered harmful’
considered harmful », publié par l’ACM et
cité dans le Jargon File et « ‘Considered
harmful’ essays considered harmful »,
disponible sur le web. Et puisque le GO TO
est mauvais, l’inverse doit être bon ! C’est
ce que Lawrence Clark a dû se dire lorsqu’il
a spécifié une nouvelle instruction, le COME
FROM. C’est également ce que se sont dit
les auteurs d’INTERCAL, lorsqu’ils ont
effectivement implémenté le COME FROM. À
noter que Clark avait également spécifié
le computed COME FROM et le assigned
COME FROM. En 1987, l’un des lauréats
de l’IOCCC (International Obfuscated
C Code Contest) fut Spencer Hines,
grâce à un programme qui contenait
une bonne vingtaine de goto. De plus, ce
programme déclarait quelques variables
entières toog, togo, oogt, ootg, otog,
des variables chaînes de caractères toog,
ogto, tgoo et ainsi de suite. Quant aux
labels vers lesquels pointent les goto, je
n’ai pas besoin de vous faire un dessin.
Et finalement, le style d’indentation
mérite d’être appelé « style », mais pas
« indentation ».
To go or not to go ?
Supprimer les goto
Puisque programmer avec des goto est
si néfaste, il a fallu proposer d’autres
solutions aux programmeurs pour qu’ils
arrêtent de cuisiner du spaghetti code.
Nous allons vous en présenter quelquesunes, que vous avez certainement déjà
rencontrées.
La construction de Jacopini
Il y a la construction de Jacopini, déjà
citée ci-dessus, mais c’est un exemple
à ne pas suivre. Vous pourrez en juger
par vous-mêmes vers la fin de cet article,
nous vous en donnons un échantillon.
Les exceptions
La programmation par exceptions permet
également de supprimer nombre de
goto. Jusqu’alors, lorsqu’une erreur était
rencontrée, on avait le choix entre la traiter
immédiatement (en encombrant ainsi le
code principal avec du code de traitement
d’erreur souvent aussi gros que le code
du traitement principal, si ce n’est plus)
ou bien renvoyer l’exécution (par un goto)
vers une section du programme prévue à
cet effet (mais en transformant le code en
un peu ragoûtant plat de spaghetti, avec
des renvois dans toutes les directions).
Comme nous l’avons dit précédemment,
le langage Java n’a pas de goto. Ceci
s’explique par le fait que les instructions
break et continue (avec étiquettes)
remplacent la plupart des utilisations
importantes et légitimes de goto et que
le mécanisme des exceptions remplace
les autres. Le mécanisme des exceptions
permet de définir un bloc d’essai (dit
« try ») dans lequel le programme va
exécuter des appels de méthodes
qui risquent de planter. Pour indiquer
l’apparition d’une condition exceptionnelle,
le bloc de code ou la méthode à laquelle
il a fait appel va lever (throw) une
exception : le traitement cesse alors et
l’exception va se propager jusqu’à sa
capture. Les exceptions se propagent au
niveau des blocs lexicaux, puis le long de
la pile d’appel des méthodes. La capture
des exceptions se fait dans le premier
bloc catch rencontré. On peut alors soit
traiter les cas d’erreurs attendus, soit
lever de nouvelles exceptions qui seront
éventuellement capturées au niveau
supérieur. Toute exception qui passe au
travers des mailles des différents filets
(euh, blocs catch) mis sur son chemin
finira par remonter jusqu’à l’utilisateur,
qui verra alors son programme planter
à cause d’une exception non capturée.
Ainsi, au lieu de s’inquiéter de ce qui
peut mal se passer à chaque ligne de
code, on va centraliser le traitement des
erreurs associées à un bloc logique de
code dans un seul bloc de traitement. Ce
qui rend ce mécanisme très intéressant,
c’est que les méthodes des bibliothèques
standards donnent la liste exhaustive des
exceptions qu’elles peuvent lever et que
le compilateur impose de préciser dans la
signature de ces méthodes les exceptions
qu’elles peuvent lever. Ainsi, si une
méthode de votre classe fait appel à une
méthode qui lève une exception d’entrée/
sortie et que votre code ne la traite pas,
il vous imposera de déclarer que vous
risquez de la propager. Bien sûr, cette
technique a aussi ses limites. En Java,
nombre de programmeurs paresseux
(dans le mauvais sens du terme) ne
traitent pas toutes les exceptions qui
peuvent se produire et se contentent de
les propager. De proche en proche, les
exceptions remontent toute la pile d’appels
et c’est l’utilisateur qui se retrouve démuni
face à une pile d’appels longue comme
un jour sans pain. Il existe d’ailleurs un
module Perl qui se moque gentiment
des programmes « professionnels »
qui plantent en générant un message
désespérément long et détaillé : Acme::
JavaTrace.
Literate Programming
La programmation littéraire (Literate
Programming), inventée par Don Knuth,
vise à écrire des programmes comme
on écrit des livres. Le programme est
présenté en langue naturelle, d’une façon
logique, avec de multiples renvois vers le
code effectuant les opérations.
Le code de traitement d’erreurs va être
typiquement relégué à une autre partie
Goto en Perl
du fichier source et ne va pas encombrer
l’esprit du programmeur qui essaye déjà
de comprendre ce que fait le bloc de
code qu’il est en train de lire. Ce projet
s’appelle « WEB » (son nom date d’avant
la création du World-Wide Web et Knuth
expliquait ce choix par le fait que c’était
l’un des rares acronymes de trois lettres
non encore utilisé) et est au cœur de TeX
et LaTeX. Ainsi les fichiers source LaTeX
contiennent leur propre documentation
(en LaTeX) et la description de leur code
(accompagnée du code lui-même). Lors
de la génération des fichiers associés,
la documentation est compilée et mise à
disposition au format .dvi tandis que le
code lui même (fichiers .sty en général)
est installé là où LaTeX ira le chercher.
WEB a donné naissance à CWEB, qui est
un ensemble de programmes permettant
de produire la documentation et les
binaires à partir de code source C écrit
selon la méthode literate.
Les utilisations légitimes de goto
goto est utilisé à plusieurs endroits du
noyau Linux (et dans de nombreux autres
systèmes et logiciels complexes). Estce que les développeurs du kernel sont
de mauvais programmeurs ? Non, bien
sûr ; goto est souvent le seul moyen de
se sortir de cas complexes, typiquement
pour la gestion d’erreurs. Les analyseurs
syntaxiques (et les machines à états)
sont aussi un cas d’utilisation légitime de
goto. Nous vous invitons par exemple à
examiner le code du module HTML::Parser
2.25 (disponible sur CPAN), dernière
version pour Perl de cet analyseur HTML
(les suivantes sont en XS, pour des
raisons de performance). De nos jours,
il existe des alternatives structurées
aux utilisations légitimes de goto les
plus courantes. Aux constructions de
boucles while ou until sont associées
les instructions break, redo ou continue
qui permettent de quitter la boucle par le
début ou la fin et d’effectuer un traitement
à chaque tour de boucle, même si celle-ci
a été interrompue.
Perl et goto
You can also « goto hell » if you like,
which will of course work better if you’ve
defined the label « hell ». (Larry Wall, The
Perl Conference, 20 août 1997)
Quand on y réfléchit, qu’est-ce qu’un
goto ? C’est un saut à un autre point
du programme, en général conditionné
par un test. Ceci se fait sans aucune
initialisation (contrairement à l’appel d’un
sous-programme). Le test de la condition
ne fait bien sûr pas partie du goto.Nous
allons donc nous intéresser aux différentes
manières de sauter d’un point à un autre
d’un programme Perl, sans initialisation,
ce qui exclut les appels à des sousprogrammes et l’utilisation de références
à des fonctions (tables de distribution).
Les « goto structurés »
Dans de nombreux cas de traitements
en boucle, on souhaite pouvoir définir
d’autres points de sortie que la fin de
la boucle, répéter une itération sans
tester la condition de sortie ou encore
sortir de plusieurs niveaux de boucles
imbriquées d’un seul coup. En Perl, les
instructions next, last et redo permettent
de résoudre ces différents cas de figure
sans faire appel au goto ni introduire tests
et variables inutiles dans le corps de la
boucle.Ces instructions sont toutes des
genres de goto, puisqu’elles permettent
de sauter à diverses positions dans la
boucle (ou juste en dehors). Le bloc
continue associé à la boucle while permet
quant à lui d’assurer que la partie finale
de la boucle sera exécutée même quand
on la court-circuite. Quand nous parlons
de « genres de goto », il s’agit bien d’une
comparaison, car comme le précise la
documentation de Perl : A loop LABEL is
not actually a valid target for a goto; it’s
just the name of the loop. (L’étiquette
d’une boucle n’est pas une cible valide
pour un goto, il s’agit juste du nom de la
boucle.)
last
La commande last permet de sortir
immédiatement d’une boucle. Elle accepte
une étiquette optionnelle pour indiquer de
quelle boucle on veut sortir, dans le cas de
plusieurs boucles imbriquées. Sinon, on
sort de la boucle la plus petite contenant
l’instruction last.
while(<>) {
# sort de la boucle
last if /^__END__/;
...
}
# pour continuer ici
Avec plusieurs boucles imbriquées :
EXTERNE:
for my $i ( @indexes ) {
}
INTERNE:
for my $j ( @jndexes ) {
...
last EXTERNE if $j == 42;
}
last ne peut pas être utilisé pour sortir
d’un bloc eval {}, sub {} ou do {} (car
ceux-ci renvoient une valeur). Il ne peut
pas non plus être utilisé pour sortir du
bloc de code exécuté par une instruction
grep() ou map().
next
next permet de court-circuiter la fin de
la boucle (comme last) pour reprendre
à l’itération suivante. Les instructions
associées aux itérations des boucles sont
traitées normalement.
Ainsi, dans le cas d’une boucle for « à
la C », l’expression de modification et
l’expression de test sont exécutées. Pour
une boucle foreach, l’élément suivant de
la liste traitée est utilisé pour la variable
d’indice. Et dans le cas d’une boucle while,
le bloc continue est exécuté, ainsi que
l’expression de test associée au while.
# exemple d’analyseur de fichiers
while(<>) {
# ignore commentaires et lignes blanches
next if /^\s*(#|$)/;
chomp;
...
}
redo
L’instruction redo ramène le pointeur
d’instruction au début du bloc courant (elle
accepte également une étiquette pour les
cas de blocs imbriqués), sans exécuter
les calculs de condition de la structure
for, foreach ou while associée.
redo ne peut pas être utilisé pour ré-
essayer un bloc qui renvoie une valeur,
comme eval {}, sub {} ou do {}, ni dans
le bloc associé à une instruction grep, map
ou sort.
En revanche, sachez qu’un bloc étant
équivalent à une boucle qui ne s’exécute
qu’une seule fois, il est donc possible
d’utiliser redo pour le transformer en
construction de boucle.
continue BLOC
Les blocs continue sont associés aux
structures de boucles et sont toujours
exécutés à la fin de chaque tour de boucle
(y compris ceux interrompus par last
ou next, c’est tout l’intérêt) juste avant
l’évaluation de la clause de condition.
77
code
Ceci sert évidement quand on sort
prématurément du corps d’une boucle
avec next. L’instruction redo ne provoque
pas l’exécution du bloc continue. Les
instructions next, redo et last peuvent
parfaitement apparaître dans un bloc
continue. redo et last se comportent
comme s’ils avaient été exécutés dans le
bloc principal de la boucle. Comme next
provoque l’exécution du bloc continue, cela
peut provoquer des effets « intéressants »
(mais rarement utiles).


Notez qu’on peut tout à fait associer un bloc
continue à une boucle foreach.
En Perl objet, quand on appelle une
méthode, Perl va parcourir le tableau @ISA
de la classe pour trouver une méthode
portant ce nom. Si cette recherche ne
donne rien, Perl va alors chercher si l’une
des classes définit une méthode AUTOLOAD
qui sera alors appelée. Cette méthode
va pouvoir exécuter un traitement de
substitution pour pallier l’absence de la
méthode recherchée.
Voici un extrait du module HTTP::Message
qui utilise cette technique :
# delegate all other method calls the the _headers object.
sub AUTOLOAD
{
my $method = substr($AUTOLOAD, rindex($AUTOLOAD, ‘::’)+2);
return if $method eq „DESTROY“;
La commande goto
Malgré l’existence des commandes de
sortie de boucle, une commande goto a
tout de même son utilité. C’est ainsi qu’il
existe en fait trois formes de goto en
Perl.
goto ETIQUETTE
78
La forme goto-ETIQUETTE retrouve
l’instruction qui porte l’étiquette et
continue l’exécution à partir de ce point.
Attention, on ne peut pas s’en servir pour
sauter à l’intérieur d’un sous-programme
ou d’une boucle foreach. De même, on ne
peut entrer dans une construction qui est
supprimée par le compilateur à la phase
d’optimisation, ou pour sortir d’un bloc ou
d’une routine passée à sort().
goto EXPR
Cette forme permet de faire des goto
calculés, à la manière FORTRAN que
nous avons vue plus haut.
goto („TOTO“, „TITI“, „TUTU“)[$i];
Si le résultat de l’expression est une
étiquette qui n’existe pas, nous aurons
droit à l’erreur Can’t find label LABEL,
tandis que ce sera goto must have a label
si le résultat de l’expression est vide
(undef). Nous ne connaissons personne
ayant eu besoin d’utiliser ce type de goto.
goto &NOM
Ce goto est assez différent du goto
habituel. Il s’agit ici de sauter vers une
autre fonction de façon transparente, en
effaçant la fonction exécutant le goto de
la pile d’appel.
Cette technique est beaucoup utilisée en
combinaison avec la méthode AUTOLOAD.
}
# We create the function here so that it will not need to be
# autoloaded the next time.
no strict ‘refs’;
*$method = eval „sub { shift->{‘_headers’}->$method(\@_) }“;
goto &$method;
Ici, les méthodes inconnues sont
déléguées de façon transparente à
l’objet associé aux en-têtes du message.
La ligne qui précède le goto insère une
nouvelle référence de code dans la
table des symboles du paquetage en
question (ici, HTTP::Message) et le goto se
charge d’appeler cette fonction de façon
transparente, comme si elle avait toujours
existé à cet endroit.
Nous sortons ici du cadre que nous nous
étions imposé au début de cette partie,
car cette forme de goto est en réalité un
appel à un sous-programme.
Les
programmeurs qui découvrent
AUTOLOAD laissent souvent libre cours
à leur paresse et l’utilisent pour définir
les accesseurs de leur classe de cette
façon. Nous ne recommandons pas cette
technique, qui est à notre avis plus propice
à la création de bogues difficiles à tracer
(AUTOLOAD va par exemple essayer de
faire quelque chose même si la fonction
appelée résulte en fait d’une faute de
frappe, si votre AUTOLOAD ne provoque pas
d’erreur dans ce cas, on aura appelé une
fonction qui ne fait probablement rien.
Difficile de retrouver la faute de frappe
dans ces conditions).
Nous préférons la technique qui consiste
à compiler les accesseurs à l’avance et à
les positionner directement dans la table
des symboles du paquetage.
for my $attr (qw( name id height width )) {
no strict ‘refs’;
*{„get_$attr“} = sub { $_[0]->{$attr} };
}
Les accesseurs ainsi créés s’utilisent
comme s’ils avaient été définis avec sub.
Comme ce code est en général dans un
module chargé avec use, les fonctions sont
disponibles dès le use exécuté. Ce code
s’appuie sur les propriétés des fermetures
(closures). Notre exemple montre des
accesseurs de type get(), mais il est bien
sûr possible d’implémenter des méthodes
plus complexes ou d’utiliser plusieurs
boucles d’initialisation.
Il suffit de comparer avec le code
équivalent pour voir l’intérêt de cette
écriture au niveau de la maintenabilité et
de l’évolution du code :
# imaginez une définition plus complexe
# et trente fonctions identiques
sub get_name { $_[0]->{name} }
sub get_id
{ $_[0]->{id} }
sub get_height { $_[0]->{height} }
sub get_width { $_[0]->{width} }
Avec notre exemple, un éventuel
changement
d’implémentation
est
instantané, sans risque d’erreur à la
recopie et l’ajout d’une méthode revient
simplement à ajouter un mot dans la liste
passée au foreach.
Exemples pratiques
Maintenant que nous avons exposé
l’histoire et les alternatives au goto,
voici quelques exemples pratiques
d’utilisation.
Une routine de recherche
Supposons que l’on cherche l’adresse de
divers correspondants. Ces adresses sont
stockées à différents niveaux de mémoire,
dans une variable du programme, dans un
fichier se trouvant sur la machine locale,
dans une base de données accessible
par le réseau local ou sur Internet. Dans
un but de performances, on privilégiera
l’accès le plus rapide.
use DBI;
use WWW::Search::PagesJaunes;
my $repert = ‘/home/moi/adresses.txt’;
my $db_source = ‘???’;
my $db_user = ‘moi’;
my $db_passwd = ‘s3kr3t’;
my %adresse;
sub recherche {
my ($qui) = @_;
# Cas idéal, il est déjà en mémoire
return $adresse{$qui} if $adresse{$qui};
# Fichier local, peut-être ?
open REPERT, $repert or goto ESSAI_BDD;
while () {
my ( $lui, $ou ) = split ‘:’;
# Si trouvé, on mémorise et on renvoie
return $adresse{$lui} = $ou if $lui eq $qui;
Goto en Perl
}
close REPERT;
ESSAI_BDD:
my $dbh = DBI->connect( $data_source, $db_user, $db_passwd )
or goto ESSAI_INTERNET;
my $acces =
$dbh->prepare(„SELECT adresse FROM personnes WHERE nom = ?“);
return $dbh->selectrow_array($acces)
or goto ESSAI_INTERNET;
ESSAI_INTERNET:
my $pj = WWW::Search::Pagesjaunes->new();
$pj->find( nom => $qui, departement => “75” );
my @resultats = $pj->results();
return $resultats[0]->addresse if @resultats;
}
Cet exemple montre l’un des cas
d’utilisation admise du goto : la reprise
après erreur. Cette fonction est lisible pour
deux raisons : tous les goto descendent
et la fonction tient sur une page d’écran
(nous sommes désolés si la pagination du
magazine fait que ce n’est pas le cas sur
le papier).
La variante sans goto aurait conduit à
utiliser un indicateur booléen et à enrober
chacun des accès élémentaires read,
fetch ou get par un test vérifiant le succès
de l’accès précédent open, connect.
En fait, on peut également se passer
complètement de l’utilisation de goto
pour cet exemple, en utilisant des tables
de distribution (dispatch tables, voir
l’article « Perles de Mongueurs » à ce
sujet dans GNU/Linux Magazine 65).
Cette technique a l’avantage d’être plus
facilement extensible.
my %adresse;
# table de distribution des méthodes utilisables
# l’ordre alphabétique des clés permet de définir
# l’ordre de préférence des techniques de recherche
my %recherche = (
r00_memoire => sub { return $adresse{$_[0]} } #
déclaration en ligne
r01_local
=> \&recherche_fichier,
#
fonctions définies
r02_bdd
=> \&recherche_bdd,
# un
peu plus loin
r03_internet => \&recheche_internet,
# dans
le script
);
sub recherche {
my ($qui) = @_;
my $adresse;
for my $essai ( sort keys %recherche) {
$adresse = $recherche{$essai}->( $qui );
last if $adresse;
}
# technique de cache pour accélerer les recherches
suivantes :
# on enrichit le cache local
$adresse{$qui} = $address if defined $adresse;
}
return $adresse;
# recherche dans un fichier
my $repert = ‘/home/moi/adresses.txt’;
sub recherche_fichier {
open my $fh, $repert or return;
while (<$fh>) {
my ( $lui, $ou ) = split ‘:’;
return $ou if $lui eq $qui;
}
close $fh;
}
# recherche dans une base de données
use DBI;
my $db_source = ‘???’;
my $db_user = ‘moi’;
my $db_passwd = ‘s3kr3t’;
sub recherche_bdd {
# même code que dans l’exemple précédent
}
A:
$car = ;
goto FIN unless defined $car;
if ($car =~ /[[:alnum:]]/)
{ $ident = $car; goto B }
if ($car eq ‘“’)
{ $chaine = ‘’; goto C }
goto A;
B:
$car = ;
goto FIN unless defined $car;
if ($car =~ /[[:alnum:]]/)
{ $ident .= $car; goto B }
if ($car eq q(„))
{ $chaine = ‘’; goto C }
goto A;
C:
$car = ;
goto D if $car eq q(\\);
if ($car eq q(„))
{ store($ident, $chaine); goto A }
$chaine .= $car; goto C;
# recherche sur Internet
use WWW::Search::PagesJaunes;
sub recherche_internet {
# même code que dans l’exemple précédent
}
L’ajout d’une nouvelle technique de
recherche se cantonnera donc à l’ajout
d’une fonction dans le code et d’une clé
dans la table de hachage. Pour changer
l’ordre des tentatives, il suffit de renommer
les clés de la table de hachage.
Un analyseur lexical et
syntaxique
Nous prenons un exemple inspiré d’un
programme réel conçu par l’un des
coauteurs. Je travaillais sur un projet
pour écrire des programmes C/SQL qui
devaient être déployés dans plusieurs
pays. Dès l’origine, il a été convenu de
scinder le source de chaque programme
en au moins deux fichiers, toto.c qui
contient les traitements et toto.h qui
contient quelques déclarations du genre :
#define MSG „C’est planté !“
char *url = „http://www.mongueurs.net/“;
char *actions [] = { „PUT“, „GET“, „POST“ };
char *histoire [] = { “Il demanda : \”Quand ?\”\n”,
“Elle répondit : \“Demain...\x22\n“ };
Et c’est à moi qu’est revenue la tâche de
spécifier les utilitaires permettant d’extraire
les chaînes à traduire et de réinjecter les
chaînes traduites. Comme les fichiers en
entrée obéissaient à une syntaxe C très
simplifiée, l’extraction pouvait se baser
sur un automate à quatre états (dans la
réalité un peu plus, les fichiers pouvant
contenir des commentaires). Voici ce que
cela donne en Perl :
#!/usr/local/bin/perl
#
# Extraction des libellés d’un source C simplifié
#
use strict;
use warnings;
local $/ = \1; # lecture caractère par caractère
my $ident;
my $chaine;
my $car;
open IN, $ARGV[0] or die “Problème avec le fichier“;
D:
$car = ;
$chaine .= q(\\) . $car; goto C;
FIN:
print “Fini !\n”;
sub store {
my ($ident, $chaine) = @_;
print “$ident -> $chaine\n” # En fait un ordre SQL
}
Au fait, nous vous avions promis un
exemple de la méthode de Jacopini pour
éliminer les GOTO. Voici ce que donnerait
cette méthode :
#!/usr/local/bin/perl
#
# Extraction des libellés d’un source C simplifié
# avec la méthode de Jacopini
#
use strict;
use warnings;
local $/ = \1; # caractère par caractère
my $ident;
my $chaine;
my $car;
open IN, $ARGV[0] or die “Problème avec le fichier“;
my $etiq = ‘A’;
while ($etiq ne ‘FIN’)
{
if ($etiq eq ‘A’)
{
$car = ;
if (not defined $car)
{ $etiq = ‘FIN’ }
elsif ($car =~ /[[:alnum:]]/)
{ $ident = $car; $etiq = ‘B’ }
elsif ($car eq ‘”’)
{ $chaine = ‘’; $etiq = ‘C’ }
else
{ $etiq = ‘A’ }
}
if ($etiq eq ‘B’)
{
$car = ;
if (not defined $car)
{ $etiq = ‘FIN’ }
elsif ($car =~ /[[:alnum:]]/)
{ $ident .= $car; $etiq = ‘B’ }
elsif ($car eq q(“))
{ $chaine = ‘’; $etiq = ‘C’ }
else
{ $etiq = ‘A’ }
}
if ($etiq eq ‘C’)
{
$car = ;
if ($car eq q(\\))
{ $etiq = ‘D’ }
elsif ($car eq q(“))
{ store($ident, $chaine); $etiq = ‘A’ }
else
{ $chaine .= $car; $etiq = ‘C’ }
}
79
code
sub AUTOLOAD {
if ($etiq eq ‘D’)
{
$car = ;
$chaine .= q(\\) . $car; $etiq = ‘C’;
}
# notre classe n’a pas de méthode DESTROY
return if $AUTOLOAD =~ /::DESTROY/;
# la fonction rights() renvoie la liste des droits
# associés à cet utilisateur dans la base
if( $AUTOLOAD =~ /::is_(\w+)$/ ) {
my $attr = $1;
no strict ‘refs’;
}
print “Fini !\n”;
sub store {
my ($ident, $chaine) = @_;
print “$ident -> $chaine\n”
}
# crée la méthode et l’insère dans la table des symboles
# du paquetage en cours (celui de la classe)
*{$AUTOLOAD} = sub { $_[0]->rights()->{$attr} };
Vous serez, je pense, d’accord avec
Dijkstra, Knuth et nous-mêmes, cette
version est illisible !
La méthode AUTOLOAD
80
Voici
un
exemple
d’utilisation
d’AUTOLOAD pour définir le plus tard
possible (à l’exécution) le code d’une
fonction. C’est le cas usuel d’utilisation du
goto routine en Perl. L’exemple de code
ci-après est utilisé en production pour
définir des accesseurs associés à des
valeurs extraites d’une base de donnée.
Une table rights définit des associations
user_id, right_id, où l’identificateur du
droit est une simple chaîne de caractères
(admin, support, etc.). Les méthodes is_
admin(), is_support(), etc. sont utilisées
dans d’autres parties du code et dans
des templates pour déterminer ce à quoi
l’utilisateur connecté a accès.
}
}
# appel la méthode de façon transparente
goto &{$AUTOLOAD};
de nouveaux mots-clés pour faciliter la
programmation structurée. C’est pourquoi
en Perl, le goto « classique » est réservé
à certains types de programmes et ne doit
pas être utilisé pour la sortie de boucles,
la gestion d’exception ou l’émulation
d’une instruction case. Le goto routine de
Perl n’est pas couvert par les réticences
d’Edsger Dijkstra : c’est un moyen très
courant de manipuler la pile d’appels,
qui est souvent utilisé en programmation
objet en Perl.
# meurt si une méthode inconnue a été appelée
croak „AUTOLOAD: Unknown method $AUTOLOAD“;
Avec cette technique, les méthodes
d’accès aux droits n’ont pas a être
ajoutées au fur et à mesure qu’on invente
de nouvelles catégories d’utilisateurs et
on garantit qu’elles sont toutes codées de
la même façon.
Auteurs
Conclusion
Jean Forget
Jean Forget pratique Perl depuis 1998
et a quasiment cessé d’utiliser C et awk
depuis cette date. Il est secrétaire de
l’association « Les Mongueurs de Perl »,
ainsi que membre du groupe de Paris.
Il a participé en tant que correcteur à
la traduction de la troisième édition de
Programming Perl.
Vous l’avez constaté, il existe de nombreux
cas en programmation où l’instruction goto
est appropriée. Mais depuis la polémique
autour de l’utilisation du goto, les
langages de programmation ont adopté
Philippe “BooK” Bruhat,
<book@ mongueurs.net>
Philippe Bruhat est président de
l’association « Les Mongueurs de Perl »
(http://www.mongueurs.net/), membre
Annexe
Si vous avez lu l’article de Knuth, vous n’avez peut-être pas prêté J’ai vu ces phrases traduites ainsi :
attention à l’expression « four-letter words like goto » utilisée par
Mauvais Elle n’employait jamais un mot de cinq ou six lettres
Knuth. Moi, si. En effet, elle faisait écho à un article que j’ai écrit
quand un mot de quatre lettres pouvait suffire. Elle avait un
en d’autres circonstances pour un autre public.
langage ordurier auquel même nous, vieux pilotes de chasse,
En dehors de la programmation Perl, je pratique les jeux de n’arrivions pas à nous faire.
simulation historique (wargames). La plupart sont en anglais,
La traduction correcte serait plutôt :
mais on trouve parfois des traductions pour certains. À force de
lire des mauvaises traductions (dont certaines venaient de ma Bon Elle n’employait jamais un mot de six ou sept lettres quand
plume :-(), j’ai décidé de mettre par écrit un certain nombre de un mot de cinq lettres pouvait suffire. Elle avait un langage
conseils concernant la traduction de l’anglais vers le français, ordurier auquel même nous, vieux pilotes de chasse, n’arrivions
conseils que l’on n’apprend pas toujours au collège ou au lycée. pas à nous faire.
Pour l’extrait suivant, vous aurez peut-être besoin de revoir la
première heure de L’Étoffe des Héros et de réviser votre Histoire
de France, ou bien, de chercher les noms propres dans votre
moteur de recherche favori (méfiez-vous des homonymes :
cherchez « général Pierre Koenig » dans les pages en français).
Si vous avez vu L’Étoffe des Héros, vous vous souvenez
peut-être de Pancho Barnes, la tenancière du saloon de la
base d’Edwards, un personnage haut en couleurs. Dans son
autobiographie, Chuck Yeager la décrit ainsi :
V.O. Pancho would never use a five- or six-letter word when a
four-letter word would do. She had the filthiest mouth that any of
us fighter jocks had ever heard.
Et pourquoi ? Parce que pour les Français, les termes « un
mot de cinq lettres » ne désignent pas n’importe quel mot de
la longueur indiquée, mais un mot bien particulier. Vous savez,
le « mot de Cambronne », que le général Koenig, assiégé à Bir
Hakeim, aurait prononcé quand on lui proposait de se rendre.
De même, l’expression « four-letter word » désigne pour les
Américains, non pas un mot, mais une série de mots à usage...
disons, spécialisé. Cela va du « Nuts » anodin du général
McAuliffe, assiégé à Bastogne en 1944 (1) aux deux mots S**t et
F**k que vous connaissez bien, en passant par d’autres que je
ne vous enseignerai pas. Par conséquent, la véritable traduction
de « four-letter word » est « mot de cinq lettres ». Par extension,
dans la phrase citée en exemple, il faudra traduire « five or six »
par « six ou sept »(2).
(1) Comme quoi, les généraux commandant des troupes d’élite (Vieille Garde, Légion Étrangère, Parachutistes) ont parfois les mêmes idées.
À propos, quelqu’un peut-il m’indiquer quel mot grossier fut proféré par Fingon, le Haut-Roi des Noldor, encerclé à la bataille des Larmes Innombrables ? ;-)
(2) Pour en revenir à la phrase de Knuth, le nombre de lettres n’a aucun intérêt. La traduction qui s’impose serait donc : « des mots obscènes comme goto ».
Goto en Perl
des groupes Paris.pm et Lyon.pm. Il
est consultant en Perl et en sécurité et
l’auteur des modules Log::Procmail, HTTP::
Proxy, Regexp::Log et Acme::MetaSyntactic,
disponibles sur CPAN. Dans HTTP::
Proxy, il est fier d’avoir utilisé deux des
Références
goto
Edsger W. Dijkstra, Go To Statement
Considered Harmful
http://www.acm.org/classics/oct95/
Pendant près de quarante ans, Dijkstra
a tenu une correspondance abondante
avec ses collègues chercheurs. La plupart
de ces manuscrits ont été transcrits et
sont disponibles sur l’Edsger W. Dijkstra
Archive : http://www.cs.utexas.edu/
users/EWD/
Donald E. Knuth, « Structured
Programming with go to Statements »,
Computing Surveys, Vol. 6, No. 4,
December 1974.
Literate Programming (CSLI Lectures
Notes 27, 1992) reprend cet article et bien
d’autres.
R. Lawrence Clark, « A
Linguistic Contribution of GOTO-less
Programming », DATAMATION, décembre
1973.
http://www.fortranlib.com/gotoless.htm
Jargon : considered harmful
http://catb.org/~esr/jargon/html/C/
considered-harmful.html
Langages de
programmation
Wikipedia : « Timeline of Programmin
g Languages »
http://en.wikipedia.org/wiki/Timeline_
of_programming_languages
International Obfuscated C Code
Contest http://www.ioccc.org/years.
html#1987_hines
Des références sur FORTRAN
http://www.pgroup.com/ppro_docs/
pgf77_ref/f77ref.htm
Des références sur COBOL
http://www.csis.ul.ie/COBOL/default.
htm http://home.swbell.net/mck9/cobol/
cobol.html
Perl Club
Les règles du Perl Club sont listées sur le
site de Dave Cross,
http://www.dave.org.uk/perlclub.html
Ces règles sont bien sûr inspirées du film
Fight Club de David Fincher, avec Edward
Norton et Brad Pitt,
http://www.imdb.com/title/tt0137523/
trois formes de goto pour créer un minianalyseur de HTML (goto ETIQUETTE,
redo) et pour créer des objets avec des
méthodes spécifiques à chaque instance
(goto &CODEREF). Il vous invite à venir
nombreux à la prochaine conférence Perl
francophone, Les Journées Perl 2005,
qui auront lieu à Marseille, les 9 et 10 juin
2005. http://conferences.mongueurs.
net/fpw2005/
Références
perlfunc(1)
Cette page de manuel contient la documentation de goto, last, next, redo et continue.
perlref(1)
Le point 4 de la section Making references explique en détail ce que sont les closures.
perlfaq7(1)
La FAQ de Perl contient également une définition des closures. Vous pouvez y accéder
directement par la commande perldoc -q closure.
Java : « Handling Errors with Exceptions » Chapitre consacré aux exceptions dans le
tutoriel Java, http://java.sun.com/docs/books/tutorial/essential/exceptions/index.html
INTERCAL
Le premier langage à implémenter le COME FROM,
http://www.catb.org/~esr/intercal/
2
sites
incontournables
Toute l’actualité du magazine sur :
www.gnulinuxmag.com
Abonnements et anciens numéros en vente sur :
www.ed-diamond.com
81
Creative Commons
Paternité - Pas d'Utilisation Commerciale - Pas de Modification 2.0
Creative Commons n'est pas un cabinet d'avocats et ne fournit pas de services de conseil juridique. La distribution de la présente
version de ce contrat ne crée aucune relation juridique entre les parties au contrat présenté ci-après et Creative Commons. Creative
Commons fournit cette offre de contrat-type en l'état, à seule fin d'information. Creative Commons ne saurait être tenu responsable
des éventuels préjudices résultant du contenu ou de l'utilisation de ce contrat.
Contrat
L'Oeuvre (telle que définie ci-dessous) est mise à disposition selon les termes du présent contrat appelé Contrat Public Creative
Commons (dénommé ici « CPCC » ou « Contrat »). L'Oeuvre est protégée par le droit de la propriété littéraire et artistique (droit
d'auteur, droits voisins, droits des producteurs de bases de données) ou toute autre loi applicable. Toute utilisation de l'Oeuvre
autrement qu'explicitement autorisée selon ce Contrat ou le droit applicable est interdite.
L'exercice sur l'Oeuvre de tout droit proposé par le présent contrat vaut acceptation de celui-ci. Selon les termes et les obligations du
présent contrat, la partie Offrante propose à la partie Acceptante l'exercice de certains droits présentés ci-après, et l'Acceptant en
approuve les termes et conditions d'utilisation.
1. Définitions
a. « Oeuvre » : oeuvre de l'esprit protégeable par le droit de la propriété littéraire et artistique ou toute loi applicable et qui
est mise à disposition selon les termes du présent Contrat.
b. « Oeuvre dite Collective » : une oeuvre dans laquelle l'oeuvre, dans sa forme intégrale et non modifiée, est assemblée en
un ensemble collectif avec d'autres contributions qui constituent en elles-mêmes des oeuvres séparées et indépendantes.
Constituent notamment des Oeuvres dites Collectives les publications périodiques, les anthologies ou les encyclopédies. Aux
termes de la présente autorisation, une oeuvre qui constitue une Oeuvre dite Collective ne sera pas considérée comme une
Oeuvre dite Dérivée (telle que définie ci-après).
c. « Oeuvre dite Dérivée » : une oeuvre créée soit à partir de l'Oeuvre seule, soit à partir de l'Oeuvre et d'autres oeuvres
préexistantes. Constituent notamment des Oeuvres dites Dérivées les traductions, les arrangements musicaux, les
adaptations théâtrales, littéraires ou cinématographiques, les enregistrements sonores, les reproductions par un art ou un
procédé quelconque, les résumés, ou toute autre forme sous laquelle l'Oeuvre puisse être remaniée, modifiée, transformée
ou adaptée, à l'exception d'une oeuvre qui constitue une Oeuvre dite Collective. Une Oeuvre dite Collective ne sera pas
considérée comme une Oeuvre dite Dérivée aux termes du présent Contrat. Dans le cas où l'Oeuvre serait une composition
musicale ou un enregistrement sonore, la synchronisation de l'oeuvre avec une image animée sera considérée comme une
Oeuvre dite Dérivée pour les propos de ce Contrat.
d. « Auteur original » : la ou les personnes physiques qui ont créé l'Oeuvre.
e. « Offrant » : la ou les personne(s) physique(s) ou morale(s) qui proposent la mise à disposition de l'Oeuvre selon les termes
du présent Contrat.
f. « Acceptant » : la personne physique ou morale qui accepte le présent contrat et exerce des droits sans en avoir violé les
termes au préalable ou qui a reçu l'autorisation expresse de l'Offrant d'exercer des droits dans le cadre du présent contrat
malgré une précédente violation de ce contrat.
2. Exceptions aux droits exclusifs. Aucune disposition de ce contrat n'a pour intention de réduire, limiter ou restreindre les
prérogatives issues des exceptions aux droits, de l'épuisement des droits ou d'autres limitations aux droits exclusifs des ayants droit
selon le droit de la propriété littéraire et artistique ou les autres lois applicables.
3. Autorisation. Soumis aux termes et conditions définis dans cette autorisation, et ceci pendant toute la durée de protection de
l'Oeuvre par le droit de la propriété littéraire et artistique ou le droit applicable, l'Offrant accorde à l'Acceptant l'autorisation mondiale
d'exercer à titre gratuit et non exclusif les droits suivants :
a. reproduire l'Oeuvre, incorporer l'Oeuvre dans une ou plusieurs Oeuvres dites Collectives et reproduire l'Oeuvre telle
qu'incorporée dans lesdites Oeuvres dites Collectives;
b. distribuer des exemplaires ou enregistrements, présenter, représenter ou communiquer l'Oeuvre au public par tout procédé
technique, y compris incorporée dans des Oeuvres Collectives;
c. lorsque l'Oeuvre est une base de données, extraire et réutiliser des parties substantielles de l'Oeuvre.
Les droits mentionnés ci-dessus peuvent être exercés sur tous les supports, médias, procédés techniques et formats. Les droits cidessus incluent le droit d'effectuer les modifications nécessaires techniquement à l'exercice des droits dans d'autres formats et
procédés techniques. L'exercice de tous les droits qui ne sont pas expressément autorisés par l'Offrant ou dont il n'aurait pas la
gestion demeure réservé, notamment les mécanismes de gestion collective obligatoire applicables décrits à l'article 4(d).
4. Restrictions. L'autorisation accordée par l'article 3 est expressément assujettie et limitée par le respect des restrictions
suivantes :
a. L'Acceptant peut reproduire, distribuer, représenter ou communiquer au public l'Oeuvre y compris par voie numérique
uniquement selon les termes de ce Contrat. L'Acceptant doit inclure une copie ou l'adresse Internet (Identifiant Uniforme de
Ressource) du présent Contrat à toute reproduction ou enregistrement de l'Oeuvre que l'Acceptant distribue, représente ou
communique au public y compris par voie numérique. L'Acceptant ne peut pas offrir ou imposer de conditions d'utilisation
de l'Oeuvre qui altèrent ou restreignent les termes du présent Contrat ou l'exercice des droits qui y sont accordés au
bénéficiaire. L'Acceptant ne peut pas céder de droits sur l'Oeuvre. L'Acceptant doit conserver intactes toutes les
informations qui renvoient à ce Contrat et à l'exonération de responsabilité. L'Acceptant ne peut pas reproduire, distribuer,
représenter ou communiquer au public l'Oeuvre, y compris par voie numérique, en utilisant une mesure technique de
contrôle d'accès ou de contrôle d'utilisation qui serait contradictoire avec les termes de cet Accord contractuel. Les mentions
ci-dessus s'appliquent à l'Oeuvre telle qu'incorporée dans une Oeuvre dite Collective, mais, en dehors de l'Oeuvre en ellemême, ne soumettent pas l'Oeuvre dite Collective, aux termes du présent Contrat. Si l'Acceptant crée une Oeuvre dite
Collective, à la demande de tout Offrant, il devra, dans la mesure du possible, retirer de l'Oeuvre dite Collective toute
référence au dit Offrant, comme demandé. Si l'Acceptant crée une Oeuvre dite Collective, à la demande de tout Auteur, il
devra, dans la mesure du possible, retirer de l'Oeuvre dite Collective toute référence au dit Auteur, comme demandé.
b. L'Acceptant ne peut exercer aucun des droits conférés par l'article 3 avec l'intention ou l'objectif d'obtenir un profit
commercial ou une compensation financière personnelle. L'échange de l'Oeuvre avec d'autres Oeuvres protégées par le
droit de la propriété littéraire et artistique par le partage électronique de fichiers, ou par tout autre moyen, n'est pas
considéré comme un échange avec l'intention ou l'objectif d'un profit commercial ou d'une compensation financière
personnelle, dans la mesure où aucun paiement ou compensation financière n'intervient en relation avec l'échange
d'Oeuvres protégées.
c. Si l'Acceptant reproduit, distribue, représente ou communique l'Oeuvre au public, y compris par voie numérique, il doit
conserver intactes toutes les informations sur le régime des droits et en attribuer la paternité à l'Auteur Original, de manière
raisonnable au regard au médium ou au moyen utilisé. Il doit communiquer le nom de l'Auteur Original ou son éventuel
pseudonyme s'il est indiqué ; le titre de l'Oeuvre Originale s'il est indiqué ; dans la mesure du possible, l'adresse Internet ou
Identifiant Uniforme de Ressource (URI), s'il existe, spécifié par l'Offrant comme associé à l'Oeuvre, à moins que cette
adresse ne renvoie pas aux informations légales (paternité et conditions d'utilisation de l'Oeuvre). Ces obligations
d'attribution de paternité doivent être exécutées de manière raisonnable. Cependant, dans le cas d'une Oeuvre dite
Collective, ces informations doivent, au minimum, apparaître à la place et de manière aussi visible que celles à laquelle
apparaissent les informations de même nature.
d. Dans le cas où une utilisation de l'Oeuvre serait soumise à un régime légal de gestion collective obligatoire, l'Offrant se
réserve le droit exclusif de collecter ces redevances par l'intermédiaire de la société de perception et de répartition des
droits compétente. Sont notamment concernés la radiodiffusion et la communication dans un lieu public de phonogrammes
publiés à des fins de commerce, certains cas de retransmission par câble et satellite, la copie privée d'Oeuvres fixées sur
phonogrammes ou vidéogrammes, la reproduction par reprographie.
5. Garantie et exonération de responsabilité
a. En mettant l'Oeuvre à la disposition du public selon les termes de ce Contrat, l'Offrant déclare de bonne foi qu'à sa
connaissance et dans les limites d'une enquête raisonnable :
i. L'Offrant a obtenu tous les droits sur l'Oeuvre nécessaires pour pouvoir autoriser l'exercice des droits accordés par
le présent Contrat, et permettre la jouissance paisible et l'exercice licite de ces droits, ceci sans que l'Acceptant
n'ait aucune obligation de verser de rémunération ou tout autre paiement ou droits, dans la limite des mécanismes
de gestion collective obligatoire applicables décrits à l'article 4(e);
b. L'Oeuvre n'est constitutive ni d'une violation des droits de tiers, notamment du droit de la propriété littéraire et artistique,
du droit des marques, du droit de l'information, du droit civil ou de tout autre droit, ni de diffamation, de violation de la vie
privée ou de tout autre préjudice délictuel à l'égard de toute tierce partie.
c. A l'exception des situations expressément mentionnées dans le présent Contrat ou dans un autre accord écrit, ou exigées
par la loi applicable, l'Oeuvre est mise à disposition en l'état sans garantie d'aucune sorte, qu'elle soit expresse ou tacite, y
compris à l'égard du contenu ou de l'exactitude de l'Oeuvre.
6. Limitation de responsabilité. A l'exception des garanties d'ordre public imposées par la loi applicable et des réparations
imposées par le régime de la responsabilité vis-à-vis d'un tiers en raison de la violation des garanties prévues par l'article 5 du
présent contrat, l'Offrant ne sera en aucun cas tenu responsable vis-à-vis de l'Acceptant, sur la base d'aucune théorie légale ni en
raison d'aucun préjudice direct, indirect, matériel ou moral, résultant de l'exécution du présent Contrat ou de l'utilisation de l'Oeuvre,
y compris dans l'hypothèse où l'Offrant avait connaissance de la possible existence d'un tel préjudice.
7. Résiliation
a. Tout manquement aux termes du contrat par l'Acceptant entraîne la résiliation automatique du Contrat et la fin des droits
qui en découlent. Cependant, le contrat conserve ses effets envers les personnes physiques ou morales qui ont reçu de la
part de l'Acceptant, en exécution du présent contrat, la mise à disposition d'Oeuvres dites Dérivées, ou d'Oeuvres dites
Collectives, ceci tant qu'elles respectent pleinement leurs obligations. Les sections 1, 2, 5, 6 et 7 du contrat continuent à
s'appliquer après la résiliation de celui-ci.
b. Dans les limites indiquées ci-dessus, le présent Contrat s'applique pendant toute la durée de protection de l'Oeuvre selon le
droit applicable. Néanmoins, l'Offrant se réserve à tout moment le droit d'exploiter l'Oeuvre sous des conditions
contractuelles différentes, ou d'en cesser la diffusion; cependant, le recours à cette option ne doit pas conduire à retirer les
effets du présent Contrat (ou de tout contrat qui a été ou doit être accordé selon les termes de ce Contrat), et ce Contrat
continuera à s'appliquer dans tous ses effets jusqu'à ce que sa résiliation intervienne dans les conditions décrites ci-dessus.
8. Divers
a. A chaque reproduction ou communication au public par voie numérique de l'Oeuvre ou d'une Oeuvre dite Collective par
l'Acceptant, l'Offrant propose au bénéficiaire une offre de mise à disposition de l'Oeuvre dans des termes et conditions
identiques à ceux accordés à la partie Acceptante dans le présent Contrat.
b. La nullité ou l'inapplicabilité d'une quelconque disposition de ce Contrat au regard de la loi applicable n'affecte pas celle des
autres dispositions qui resteront pleinement valides et applicables. Sans action additionnelle par les parties à cet accord,
lesdites dispositions devront être interprétées dans la mesure minimum nécessaire à leur validité et leur applicabilité.
c. Aucune limite, renonciation ou modification des termes ou dispositions du présent Contrat ne pourra être acceptée sans le
consentement écrit et signé de la partie compétente.
d. Ce Contrat constitue le seul accord entre les parties à propos de l'Oeuvre mise ici à disposition. Il n'existe aucun élément
annexe, accord supplémentaire ou mandat portant sur cette Oeuvre en dehors des éléments mentionnés ici. L'Offrant ne
sera tenu par aucune disposition supplémentaire qui pourrait apparaître dans une quelconque communication en
provenance de l'Acceptant. Ce Contrat ne peut être modifié sans l'accord mutuel écrit de l'Offrant et de l'Acceptant.
e. Le droit applicable est le droit français.
Creative Commons n'est pas partie à ce Contrat et n'offre aucune forme de garantie relative à l'Oeuvre. Creative Commons décline
toute responsabilité à l'égard de l'Acceptant ou de toute autre partie, quel que soit le fondement légal de cette responsabilité et quel
que soit le préjudice subi, direct, indirect, matériel ou moral, qui surviendrait en rapport avec le présent Contrat. Cependant, si
Creative Commons s'est expressément identifié comme Offrant pour mettre une Oeuvre à disposition selon les termes de ce Contrat,
Creative Commons jouira de tous les droits et obligations d'un Offrant.
A l'exception des fins limitées à informer le public que l'Oeuvre est mise à disposition sous CPCC, aucune des parties n'utilisera la
marque « Creative Commons » ou toute autre indication ou logo afférent sans le consentement préalable écrit de Creative Commons.
Toute utilisation autorisée devra être effectuée en conformité avec les lignes directrices de Creative Commons à jour au moment de
l'utilisation, telles qu'elles sont disponibles sur son site Internet ou sur simple demande.
Creative Commons peut être contacté à http://creativecommons.org/.

Documents pareils