|
|
Présentation du site Cours Erlang Articles Projets Autour d'Erlang-fr Liens English Area Miroir: Documentation Erlang Miroir: Archives Erlang/OTP Recherche ![]()
|
Débuter avec ErlangArticle original traduit par Philippe Midol-Monnet. 1 Débuter avec Erlang1.1 IntroductionCe chapitre décrit les opérations les plus courantes effectées avec Erlang/OTP et est destiné aux lecteurs utilisant Erlang/OTP pour la première fois. Il contient aussi des références vers des sources d'informations plus détaillés. Ce document considère que vous avez accès à d'autres sources d'informations sur le fonctionnement du langage Erlang. Le premier chapitre du livre Concurrent Programming in ERLANG est diponible en ligne au format PDF (En anglais). Ce manuel décrit comment:
Ce manuel décrit aussi les différences entre les environnements de développement sur les plateformes Unix et Windows. 1.1.1 Conventions utilisées dans ce documentLes conventions suivantes ont été utilisées pour décrire les commandes saisies au clavier dans le shell Erlang, ou dans la ligne de commande Emacs.
1.2 Travailler avec ErlangLes programmes Erlang sont lancés quand vous le demandez au moteur d'exécution d'Erlang (Erlang runtime system) (ERTS) d'exécuter votre code. Ce ne sont pas des programmes binaires qui peuvent être exécutés directement par votre ordinateur. ERTS est constitué d'un «évaluateur» de code (evaluator) Erlang et de plusieurs bibliothèques. L'évaluateur d'Erlang est aussi considéré comme un émulateur et ressemble beaucoup à la machine virtuelle Java. ERTS réunis à de nombreux composants prêt à l'emploi et un ensemble de principes de conception compose l'Open Telecom Platform, appelé aussi OTP ou Erlang/OTP. La partie centrale de l'environnement de développement d'Erlang/OTP est le shell Erlang, erl. erl est disponible sur système Unix, Windows NT/2000 et Windows 95/98. Il ressemble beaucoup à un shell Unix, au DOS sous Windows ou à la fenêtre de commande Windows NT. La différence est que le shell Erlang comprend comment:
En plus de cette interface textuelle, il existe plusieurs outils comportant une interface graphique, comme le debugger ou le gestionnaire de process. Vous pouvez effectuer toutes les opérations depuis cette interface de commande, mais vous pouvez aussi activer la barre d'outils, ou vous trouverez des boutons permettant de lancer les outils graphiques. 1.2.1 Lancement d'Erlang/OTPPour démarrer Erlang/OTP sur un syteme Unix, vous lancer dans un shell, la commande suivante: > erl -s toolbar
Sur une plateforme Windows, vous pouvez lancez Erlang/OTP en choisissant
l'option C:\> werl -s toolbar
Les informations suivantes apparaissent a l'écran: Erlang (BEAM) emulator version 4.9
Eshell V4.9 (abort with ^G)
1>
Le shell Erlang est maintenant prêt à recevoir vos instructions. Ces commandes peuvent être n'importe quelle expression compréhensible par un shell Erlang. Essayez en tapant Erlang (BEAM) emulator version 4.9
Eshell V4.9 (abort with ^G)
1> 1 + 2.
3
2> date().
{1998,1,22}
L'exemple ci-dessus peut être vu comme un dialogue avec le moteur d'exécution. Vous pouvez aussi lancer des fonctions ou des programmes, envoyer des messages ou contrôler des process. Pour arrêter Erlang/OTP, saisissez une des commandes suivantes dans la fenêtre d'exécution:
1.2.2 Démarrage des outilsVous pouvez démarrer différents outils depuis la barre d'outils. ![]() La barre d'outils (Toolbar) 1.2.3 Compiler un fichier Cette section décrit coment compiler et exécuter un programme Erlang simple
en utilisant le shell Erlang. Nous considérons que le programme
suivant, qui calcul la factoriel d'un entier, a été créé avec un
éditeurs externe, et qu'il a été sauvé sous le nom de
Assurez vous que vous êtes dans le répertoire, ou se trouve le fichier contenant le programme.
Vous pouvez utilisez la commande -module(math1).
-export([factorial/1]).
factorial(0) -> 1;
factorial(N) -> N * factorial(N-1).
Suivez les indications suivantes pour compiler le programme:
Voir la section Compilation dans ce chapitre pour plus d'information sur la compilation du code 1.2.4 Evaluer une expressionQuand un module a été compilé avec succès, les fonctions exportées de ce modules peuvent être évaluées en saisissant l'expression au prompt du shell Erlang, suivi par un point et un retour chariot. L'exemple suivant illustre une évaluation, utilisant le
programme
1.2.5 Arrèter l'évaluation d'une expressionEntrez C-c. pour stopper une évaluation (appuyez sur la touche Control et la lettre c simultanément). Cette action permet aussi de terminer une boucle infinie. 1.2.6 Comment obtenir de l'aideLe langage Erlang lui-même est décris dans le livre Concurrent Programming in ERLANG , qui est disponible en ligne au format PDF. NdT : Concurrent se traduit par concourrant (aller ensemble) et non par concurrent (l'inverse). La documentation complète au format HTML peut-être téléchargée avec l'environnement de développement lui-même (Archive). Elle est aussi disponible en ligne Depuis un shell Unix vous pouvez accéder aux pages de manuel des
bibliothèques d'Erlang/OTP. Par exemple pour visualiser le manuel du
module intitulé % erl -man lists
Vous pouver lister les commandes du shell Erlang en tapant 1> help().
1.3 Le shell ErlangLe shell Erlang est un programme donnant accès à l'«évaluateur» Erlang. Les commandes éditées, les commandes internes du shell, et les expressions Erlang, qui sont saisies dans la fenêtre du shell sont interprétées par l'«évaluateur» Erlang. Dans le shell il est possible:
En fonction de votre environnement de travail, démarrer Erlang/OTP, d'une des façons suivantes:
![]() Le menu d'Erlang/OTP sur Windows Hormis l'évaluation des commandes et des expressions, le shell a les propriétés suivantes:
Le shell peut fonctionner en deux modes différents:
1.3.1 Commandes d'éditionL'utilisateur peut éditer les commandes grace à un sous-ensemble des commandes d'édition d'Emacs. Ces commandes sont listées dans le tableau suivant.
La touche 1.3.2 Commandes Interne du Shell Le shell possède d'origine plusieurs commandes internes. La
commande 1> help().
** shell internal commands **
b() -- display all variable bindings
e(N) -- repeat the expression in query <N>
f() -- forget all variable bindings
h() -- history
v(N) -- use the value of query <N>
** commands in module c **
c(File) -- compile and load code in <File>
cd(Dir) -- cd Dir .. example cd("..")
flush() -- flush any messages sent to the shell
help() -- help info
i() -- information about the system
ni() -- information about the networked system
i(X,Y,X) -- information about pid <X,Y,Z>
l(File) -- Load module in <File>
lc([File]) -- Compile a list of Erlang modules
ls() -- list files in the current directory
ls(Dir) -- list files in directory <Dir>
m() -- which modules are loaded
m(Mod) -- information about module <Mod>
nc(File) -- compile and load code in <File> on all nodes
nl(File) -- Load module in <File> on all nodes
pid(X,Y,Z) -- convert X,Y,Z to a Pid
pwd() -- print working directory
regs() -- information about registered processes
nregs() -- information about all registered processes
** commands in module i (interpreter interface) **
ih() -- print help for the i module
true
2>
Quand une expression au format
1.3.3 Exemple de dialogue avec le ShellCe qui suit est un dialogue complet avec le shell. Des explications détaillées sont données pour chaque commandes. host_prompt> erl
Eshell V4.4 (abort with ^G)
1> Str = "abcd".
"abcd"
La commande 1 positionnne la variable 2> L = length(Str).
4
La commande 2 "compare la forme" (matches the pattern) de 3> Descriptor = {L, list_to_atom(Str)}.
{4,abcd}
La commande 3 affecte la variable 4> L.
4
La commande 4 affiche la valeur de la variable 5> b().
Descriptor = {4,abcd}
L = 4
Str = "abcd"
ok
La commande 5 évalue la commande interne du shell 6> f(L).
ok
La commande 6 évalue la commande interne du shell 7> b().
Descriptor = {4,abcd}
Str = "abcd"
ok
La commande 7 retourne la liste des variables et de leurs contenus.
La variable 8> {L, _} = Descriptor.
{4,abcd}
La commande 8 effectue une opération d'appariement en fonction
d'un modèle, avec 9> L.
4
La commande 9 évalue 10> {P, Q, R} = Descriptor.
** exited: {{badmatch,{4,abcd},{erl_eval,expr,3}} **
La commande 10 tente d'apparier 11> P.
** exited: {{unbound, 'P'},{erl_eval, expr, 3}} **
12> Descriptor.
{4,abcd}
Les commandes 11 et 12 montrent que 13> {P, Q} = Descriptor.
{4,abcd}
14> P.
4
Les commandes 13 et 14 montrent un appariement réussi, dans lequel
15> f().
ok.
La commande 15 efface toutes les affectations Pour les autres commandes nous utiliserons le module test1 défini de la manière suivante: -module (test1).
-export ([demo/1]).
demo(X) ->
put(aa, worked),
X = 1,
X + 10.
Compilez le par 16> put(aa, hello).
undefined
17> get(aa).
hello
Les commandes 16 et 17 positionne et vérife la valeur de l'objet
18> Y = test1:demo(1).
11
19> get().
[{aa, worked}]
La commande 18 évalue 20> put(aa, hello).
worked
21> Z = test1:demo(2).
!!! Error in process <0.17.0> with exit value:
{{badmatch,1},{test1,demo,[2]}}
** exited: {{badmatch,1},{test1,demo,[2]}} **
Les commandes 20 et 21 remettent la valeur de l'objet
22> Z.
** exited: {{unbound,'Z'},{erl_eval,expr,3}} **
23> get(aa).
hello
Les commandes 22 et 23 montrent que 24> erase(), put(aa, hello).
undefined.
25> spawn(test1, demo, [1]).
<0.15.1>
26> get(aa).
hello
Les commandes 24, 25 et 26 montrent l'effet de l'évaluation de
27> io:format("hello hello\n").
hello hello
ok
28> e(27).
hello hello
ok
29> v(27).
ok
Les commandes 27, 28 et 29 utilisent les fonctionnalités d'historique
du shell. La commande 28 Dans les commandes suivantes, nous utilisons le module test2 défini de la manière suivante: -module (test2).
-export ([loop/1]).
loop(N) ->
io:format('Hello Number:~w\n', [N]),
loop(N+1).
Compilez le par 30> test2:loop(0).
Hello Number:1
Hello Number:2
Hello Number:3
Hello Number:4
Hello Number:5
User switch command
-->
La commande 30 évalue Tapez q pour quitter le shell Erlang, puis ouvrez un nouveau shell et essayez les commandes suivantes: 1> F = fun(X) -> 2*X end.
#Fun<erl_eval>
2> F(2).
4
La commande 1 associe la variable 1.3.4 Utilisation Avancée du Shell - Mode Job ControlQuand le shell démarre, il lance un unique process "évaluateur". Ce process, ainsi tout les process locaux, qu'il crée (essaime) sont appelé des jobs . Seul le job courant qui est dit connecté (Connected), peu effectuer des opérations utilisant les I/O standards. Tous les autres process sont dit detachés et seront bloqués s'ils tentent d'utiliser les I/O standards. Les jobs n'utilisant pas ces I/O standards continuerons normallement. Lorsque l'utilisateur tape -->
En tapant --> ?
c [nn] - connect to the current job
i [nn] - interrupt job
k [nn] - kill job
j - list all jobs
s - start new job
r [node] - start a remote shell
q - quit erlang
? | h - help
Les commandes JCL ont le comportement suivant.
1.4 CompilationUn fichier est compilé par l'évaluation de la fonction compile:file(File, Options).
Vous pouvez aussi entrer la commande
La fonction 1.4.1 Message du compilateursLe compilateur Erlang détecte un certain nombre d'erreurs. Cela peut être:
Le compilateur prévient aussi lors d'erreurs potentiels. 1.4.1.1 Erreurs de syntaxeLes erreurs de syntaxes sont signalées pour du code Erlang syntaxiquement incorrect. Par exemple, la partie de code suivante est incorrecte et déclenchera un message de la part du compilateur: test(X, Y) ->
case g(X) o
Y -> 1;
2 -> 2
end.
Le mot clé test1.erl: 10 : of expected before `o'
Cela signifie qu'une erreur est survenue en ligne
10 du fichier 1.4.1.2 Erreurs sur les Variables Deux types d'erreurs sur les variables peuvent être
détectées par le compilateur. Les variables peuvent être
undefined (indéfinies), ou unsafe.
Dans l'exemple suivant, les variables test(X) ->
A = f(X, Y, Z),
b(A, X).
A la compilation, le messages d'erreur suivant est affiché: ./test.erl:11: variable 'Y' is unbound
/test.erl:11: variable 'Z' is unbound
La raison de ces erreurs est que les variables
L'exemple suivant montre l'utilisation de variable peu sur (unsafe): test1(X) ->
case f(X) of
true -> Y = 1, Z = 2;
false -> Y = 2
end,
g(Y, Z).
Dans cet exemple, il y a deux branches
d'exécution possible dans le bloc case. Dans un de ces cas les
variables ./test1.erl:9: variable 'Z' is unsafe
Si aucune référence n'est faite à test2(X) ->
case f(X) of
true -> Y = 1, Z = 2;
false -> Y = 2
end,
g(Y).
Pour les deux fonctions ./test1.erl:9: Warning: variable 'Y' exported from ['case']
Pour éviter ce message et diminuer le risque de variable unsafe, il est préférable d'écrire le code comme suit: test3(X) ->
Y = case f(X) of
true -> 1;
false -> 2
end,
g(Y).
1.4.1.3 Fonctions ManquantesLe module suivant contient une fonction manquante: -module(test).
-export([test/1]).
test(X) -> try(X, abc).
Quand le module est compilé, le résultat est: > c(test).
/test.erl:3: function try/2 undefined
error
1.5 Debuggage avec le gestionnaire de ProcessLe gestionnaire de process pman, est un outil qui trace l'évaluation du code. Il est capable de tracer plusieurs process différents, et plusieurs machines différentes si un système distribué est utilisé. pman est controlé à travers une inteface graphique simple. Démarré pman comme suit:
La fenêtre suivante est affiché au démarrage de pman: ![]() L'interface de Pman Cette section décrit une session de debuggage simple, utilisant le traçage du code d'un process unique. Pour une description plus détaillée de pman voir le Guide de l'Utilisateur du Gestionnaire de Process. 1.5.1 Exemple Nous illustrerons cette exemple en traçant l'évaluation de la fonction
-module(ping_pong).
-export([ping/0, pong/0]).
ping() ->
Pong = spawn(ping_pong, pong, []),
Pong ! {self(), ping},
receive
pong ->
pong
end.
pong() ->
receive
{Ping, ping} ->
Ping ! pong
end.
Pour tracer le process, suivez ces opérations:
![]() La fenêtre de trace du shell ![]() Trace de la fonction ping_pong:ping() 1.6 Erlang DistribuéErlang peut être utilisé pour écrire des applications distribuées, qui tournent simultanément sur plusieurs ordinateurs. La programmation distribuée avec Erlang est le sujet du livre Concurrent Programming in ERLANG. Consultez aussi le Manuel de Référence. 1.6.1 Noeuds Le noeud est le concept de base d'Erlang distribué. Dans un système
Erlang distribué, le terme de noeud désigne un moteur d'exécution (runtime system)
Erlang, qui peut communiquer avec les autres systèmes Erlang.
A chaque noeud est associé un nom, qui est retourné par la
fonction de base dilbert@super.du.ericsson.se
Avant de pouvoir comprendre la structure d'un nom de noeud, il est nécessaire de connaitre comment les noms des hôtes sont constitués. 1.6.1.1 Noms des HôtesTous les hôtes, connectés au réseau, ont un numéro IP. Il n'est pas très pratique d'utiliser cette adresse IP pour désigner les hôtes car ils sont constitués d'une série de chiffres et qu'il est difficile de s'en rappeler. Pour cette raison, des noms sont donnés aux hôtes. Le nom des hôtes, connectés à Internet, sont organisés en domaines. Les domaines sont constitués hiérachiquement, avec un domaine "haut niveau" et des "sous-domaines". Par exemple, le domaine denommé du.etx.ericsson.se est un sous domaine, faisant partie d'un autre sous domaines etx.ericsson.se, qui est lui même une partie du domaine se. Lorsqu'il n'y a pas d'ambiguité possible sur le dommaine d'appartenance d'un hôte, il n'est pas nécessaire d'utiliser un nom complet. Dans l'exemple super.du.ext.ericsson.se, la premiere partie "super" suffira. On dit alors que "super" est le nom court de l'hôte (short host name). Les hôtes qui ne sont pas connectés à Internet et n'appartiennent pas à un domaine particulier, seront simplement appelé par leur nom court, "super" par exemple. Nous utilisons le terme de nom de l'hôte pour désigner le nom des hôtes. C'est le contexte qui précisera si cela sigifie le nom long ou court. 1.6.1.2 Noms des NoeudsUn nom de noeud Erlang est un atome construit par la concaténation d'un nom fourni par l'utilisateur, du caractère @, et du nom de l'hôte sur lequel le système Erlang est exécuté. Par exemple: dilbert@super.du.etx.ericsson.se
Dans cet exemple, "dilbert" est le nom du noeud Erlang, et "super.du.etx.ericsson.se" est le nom de l'hôte sur lequel tourne Erlang. Erlang distribué exige que les noms d'hôtes soient unique, puisque les noeuds Erlang s'identifient entre eux par les noms de noeuds. Nous pouvons nous assurer de l'unicité des noms des hôtes soit en utilisant des noms longs, soit en utilisant des noms courts avec la condition supplémentaire que les hôtes appartiennent au même domaine (ou que le réseau n'est pas connecté à Internet). Lorsque des noms long sont utilisés pour les hôtes, les noms de noeuds correspondant sont dit noms de noeud long. Par exemple: dilbert@super.du.etx.ericsson.se
Dans ce cas, Erlang est démarré avec l'option De même, lors de l'utilisation de nom court pour les hôtes, les noms de noeuds correpondant sont appelé noms de noeud courts. Par exemple: dilbert@super
Dans ce cas Erlang est démarré avec l'option
Le plus souvent, le contexte permet de savoir si le nom de noeud est long ou court. Dans ce cas, nous utilisons le terme nom de noeud sans préciser s'il est long ou court. La première partie du nom de noeud qui est placée avant
le caractère @ est le nom simple du noeud.
Le nom simple d'un noeud est unique par rapport a l'hôte sur
lequel il tourne. Au lancement d'Erlang avec les options
1.6.2 DémarrageExécutez la commande suivante pour démarrer un noeud Erlang distribué: % erl -name foobar
Eshell V4.4 (abort with ^G)
(foobar@super.eua.ericsson.se)1>
Le nom du noeud affiché par le système, inclu le nom de l'hôte.
Une autre façon de faire est de démarrer le système avec
l'option 1.6.3 Options du Script pour la Distribution Le script exécutable erl démarre le moteur
d'exécution d'Erlang. Consultez le Manuel de Référence,
1.6.4 Sécurité Les noeuds Erlang sont protégés par un systeme de magic cookie.
Consultez le Manuel de Référence, a la section
Les magic cookies sont assignés aux noeuds de la façon suivante:
Un noeud Erlang fonctionne sans aucune protection quand
1.6.5 Noeuds Esclaves Le module Les noeuds distants sont démarrés à l'aide des commandes Unix
Referez vous aux manuels suivant pour des informations complémentaires:
1.7 ConfigurationLe système standard Erlang/OTP peut être reconfiguré pour modifier les comportements par défaut au démarrage. 1.7.1 Le Fichier .erlang Au démarrage d'Erlang/OTP le système cherche un fichier nommé
Si un fichier Un fichier io:format("executing user profile in HOME/.erlang\n",[]).
code:add_path("/home/calvin/test/ebin").
code:add_path("/home/hobbes/bigappl-1.2/ebin").
io:format(".erlang rc finished\n",[]).
1.7.2 user_default et shell_default Les fonctions dans le shell qui ne sont pas préfixées
par un nom de module sont considérées comme des objets fonctions
(Fun), des fonctions de base (built-in), ou appartenant au module
Pour inclure des commandes shell privées, définissez les dans
un module code:load_abs("..../user_default").
1.7.3 erl Si le contenu de Copyright © 1991-2001 Ericsson Utvecklings AB |
Pour tout commentaire: erlang@erlang-fr.org
Dernière modification: 2005-11-11 18:47:49