• Aucun résultat trouvé

introduction de La mise en œuvre de Lua 5.0 en PDF

N/A
N/A
Protected

Academic year: 2021

Partager "introduction de La mise en œuvre de Lua 5.0 en PDF"

Copied!
13
0
0

Texte intégral

(1)

Appel de fonction

 Passage des arguments  Arguments variables  Valeurs de retour multiples

Il est recommandé de lire préalablement le chapître Fonctions.

Passage des arguments

Puisque Lua est typé dynamiquement et n'a aucun besoin de déclaration de type pour les fonction, la vérification du nombre et des types d'arguments exigés pour une fonction semble quelque peu superflue.

Lua sait gérér avec élégance un nombre mal adaptés d'arguments et les appels

d'arguments formels. Les arguments formels de fonction reçoivent une valeur par défaut à nil s'ils ne sont pas remplis. Là où trop d'arguments sont passés ils sont simplement ignorés.

Aucun type n'est indiqué pour chaque argument car ils sont typés dynamiquement c.-à-d. que nous devont seulement connaître le type d'un objet quand nous l'employons, pas quand nous le mettons en référence. Nous emploierons la fonction suivante comme exemple :

> function foo(a,b,c) print(a,b,c) end

Voici ce qui se produit quand nous l'appelons sans arguments : > foo()

nil nil nil

Notez que chacun des arguments s'est assigné la valeur nil, ou aucune valeur, et nous n'avons pas d'erreur. Voici ce qui se produit quand nous passons trop d'arguments : > foo(1,2,3,4)

1 2 3

Aucune erreur de constatée et le dernier argument est simplement ignoré. Puisque Lua est typé dynamiquement nous pouvons passer n'importe quel type d'argument, nous pouvons passer par exemple aussi bien des chaînes de caractères que des nombres.

> foo("hello") hello nil nil

> foo("pi", 3.1415, { comment="this is a table" }) pi 3.1415 table: 002FDBE8

Arguments variables

Il est souvent utile d'avoir un nombre variables d'arguments pour une fonction, comme par exemple pour la fonction en C printf(format,...) . Lua fait ceci, dans les versions avant 5.1, en plaçant la liste variable d'argument dans une rangée de table appelée arg,

utilisable par la fonction, par exemple: > function foo(...) print(arg) end > foo("abc",3,77)

(2)

Dans cet exemple nous pouvons seulement voir que c'est une table. Nous pouvons employer table.foreach(table,function) pour afficher les valeurs de la table d'arguments, ainsi :

> function foo(...) table.foreach(arg,print) end > foo()

n 0

En regardant une liste vide de variable d'arguments, il est facile de voir qu'une paire supplémentaire de table est ajoutée pour fournir le nombre d'éléments dans la table arg.n. Dans ce cas-ci le nombre d'arguments est zéro. Essayons de passer un nombre variable d'arguments :

> foo(1,2,3) 1 1 2 2 3 3 n 3 > foo("apple",2,"banana",99,3.1415927,foo) 1 apple 2 2 3 banana 4 99 5 3.1415927 6 function: 002FB5C8 n 6 unpack

Une fonction utile pour des arguments variables est unpack(). Ceci prend une table et renvoie une liste de variables, par exemple :

= unpack({1,2,3}) 1 2 3

Ceci peut être employé avec les listes variables d'argument comme suit : function listargs(...)

>> return unpack(arg) >> end

> = listargs(1,2,3) 1 2 3

> = listargs("hello", {1,2,3}, function (x) return x*x end) hello table: 0035F0B8 function: 00357860

Valeurs de retour multiples

Lua peut retourner plus d'une valeur à une fonction. Ceci est fait par retour d'une liste séparée par des virgules :

function foo(angle)

>> return math.cos(angle), math.sin(angle) >> end

>

> print( foo(1) ) -- returns 2 values... 0.54030230586814 0.8414709848079 >

> c,s = foo(3.142/3) -- assign the values to variables > = math.atan(s/c)

(3)

> = c,s 0.49988240461137 0.86609328686923 > > function many(x) >> return x, x*x, x*x*x, x*x*x*x, x*x*x*x*x >> end > = many(5) 5 25 125 625 3125 > = many(0.9) 0.9 0.81 0.729 0.6561 0.59049

La fonction ci-dessus pourrait avoir un nombre variable de valeurs de retour si nous construisons une table, contenant les valeurs, et l'utilisation unpack. Par exemple, function many2(x,times)

>> local t = { [0]=1 }

>> for i=1,times do t[i] = x*t[i-1] end >> return unpack(t) >> end > = many2(5,10) 5 25 125 625 3125 15625 78125 390625 1953125 9765625 > = many2(0.5,7) 0.5 0.25 0.125 0.0625 0.03125 0.015625 0.0078125

Valeurs de retour en table

Nous pouvons également renvoyer les valeurs dans une table. Pour faire ceci nous ajoutons les parenthèses bouclées autour de l'appel de fonction, qui construira une table, c.-à-d. :

{ function_name ( args )}

Voici un exemple en utilisant l'exemple précédent de fonction : = { foo(1.5) } table: 0035E088 > t = { foo(1.5) } > table.foreach(t,print) 1 0.070737201667703 2 0.99749498660405 Valeur Simple

Si une fonction renvoie des valeurs multiples, mais nous voulons seulement la première valeur, nous mettons une parenthèse autour de l'appel de fonction, c.-à-d..

( function_name ( args )) Voici un exemple : > = (foo(1.5)) 0.070737201667703 > = foo(1.5) 0.070737201667703 0.99749498660405

La même chose pourrait être réalisé en renvoyant une table et en prenant le premier élément mais la syntaxe ci-dessus est plus efficace.

(4)

> = ({foo(1.5)}) [1] 0.070737201667703

Les fonctions du noyau LUA

Tester la bonne exécution d'une fonction (assert) Nettoyage mémoire (collectgarbage)

Appeler un fichier LUA externe et executer son contenu (dofile) Affiche les erreurs d'une fonction (error)

Environnement (variable globale _ G) Obtenir l'environnement courant (getfenv(f))  Obtenir une metatable getmetatable(object)  Infos sur la mémoire (gcinfo)

Itération sur table (ipairs)

Chargement d'un fichier comme code LUA (loadfile) Chargement d'une librarie LUA (loadlib)

Chargement d'une chaîne de caractères à partir d'un fichier (loadstring) Balayage d'une table (next)

 Obtenir une paire clé valeur (pairs)

Appel de fonction en mode protégé (pcall) Impression vers la sortie standard (print) Test d'égalité (rawequal)

Obtenir la valeur brute d'un champ de table (rawget) Définir la valeur brute d'un champ de table (rawset) Chargement d'un package (require)

Positionne l'environnement (setfenv)

Défini une metatable associé à une table (setmetatable) Conversion en valeur numérique (tonumber)

Conversion en chaîne de caractères (tostring) Connaitre le type d'une variable (type)

Affiche le contenu d'une liste (unpack)  Affiche la version de LUA (_VERSION)

Appel de fonction avec traitement d'exception (xpcall )

Ces fonctions permettent d'accéder aux fonctionnalités principales (noyau) du langage Lua. Nous n'entrerons pas dans le détail de toutes les fonctions abordées ici.

Tester la bonne exécution d'une fonction (assert)

assert(test [, message ])

Semblable à la fonction en C assert(). Si la condition "test" est false ou nil une erreur est retourné sinon le traitement est effectué. Un message facultatif peut être retourné en plus du message système. Consulter la fonction error() pour plus de détails.

Par exemple:

> assert(1==1) -- no error as test was true > assert(1==0)

stdin:1: assertion failed! stack traceback:

[C]: in function `assert' stdin:1: in main chunk [C]: ?

> assert("green"=="blue", "Colours not equal") stdin:1: Colours not equal

(5)

[C]: in function `assert' stdin:1: in main chunk [C]: ?

Beaucoup de fonctions de Lua, comme io.open, renvoient une valeur sur le succès, ou renvoient nil et un message d'erreur en cas d'échec. Ceci fonctionne bien avec assert: file = assert(io.open(filename))

Ce code ouvre filename en lecture et l'assigne à la variable file, ou elle retourne un message d' erreur (2ème valeur de retour de io.open.)

Nettoyage mémoire

collectgarbage([limit ])

Fixe la limite d'attribution de mémoire à laquelle le collecteur de zone mémoire non libéré sera appelé. Si la nouvelle limite est moins que la quantité courante d'attribution de mémoire de Lua, ou aucun argument n'est donné, le collecteur est appellé

systématiquement.

Consultez le GarbageCollectionTutorial pour plus d'information.

> = gcinfo() -- trouvez la stat courante de mémoire, c.-à-d. 21kb a employé 21 35 > bigalloc = string.rep('a ', 100000) -- créez une grande chaîne de caractère > = le gcinfo() -- 164kb a assigné maintenant 164 327

> collectgarbage() -- collection de force

> = gcinfo() -- nous avons libéré une certaine mémoire sur la collection 139 278 > bigalloc = zéro -- libèrent la chaîne de caractère que nous avons créée

> = gcinfo() -- il n'est pas supprimé jusqu'à ce que ses 140 278 rassemblés > collectgarbage() -- nous rassemblons > = gcinfo() -- il est supprimé 29 59

Appeler un fichier LUA externe et executer son contenu (dofile)

dofile(filename)

Ouvre un fichier LUA et exécute son contenu comme un sous programme (chunk Lua). Appelé sans argument, dofile exécute le contenu de l'entrée standard (stdin).

Renvoie au programme appelant toutes les valeurs retournée par le programme appelé. En cas d'erreurs, dofile retourne l'erreur au programme appelant (dofile ne fonctionne pas en mode protégé).

Affiche les erreurs d'une fonction (error)

error(message [, de niveau ])

Termine la dernière fonction protégée appelée, et renvoie message comme message d'erreur.

La fonction erreur n'a pas de retour.

L'argument de niveau indique où le message d'erreur dirige l'erreur.

(6)

Le niveau 2 pointe sur l'erreur où la fonction qui a appelé erreur a été appelée ; et ainsi de suite.

Le niveau 0 évite l'ajout des positions des erreurs dans le message d'information.

Environnement (variable globale _ G)

_G est une variable globale qui contient l'environnement global de LUA.

Par exemple pour montrer toutes les variables globales nous pourrions faire ce qui suit : > table.foreach(_G,print)

: fonction de 00357098 xpcall : fonction 00354E10 tostring : fonction du gcinfo 00354708 : fonction du loadlib 00354E90 : table d'OS 00358B40

: 00355AE0 déballent la fonction

: 003547C8 le niveau 2 exigent la fonction : fonction du getfenv 00354F90

: 00354548... -- etc...

_G est également récursif . Voir exemple: > = _ table de G : 00353710

> = _ table de G._G : 00353710 > = _ table de G._G._G : 00353710

Lua lui-même n'emploie pas cette variable, ainsi changer sa valeur n'affecte pas son environnement.

Vous devriez employer setfenv() pour changer des environnements.

Obtenir l'environnement courant (getfenv(f))

getfenv(f)

Renvoie l'environnement courant de la fonction f.

f peut être une fonction de Lua ou un nombre, nombre qui indique la fonction à ce niveau de la pile :

Le niveau 1 est la fonction qui appelle getfenv.

Si la fonction donnée n'est pas une fonction de Lua, ou si f est 0, getfenv renvoie l'environnement global.

Le défaut pour f est 1.

Obtenir une metatable getmetatable(object)

getmetatable(object)

Si l'objet n'a pas un metatable, renvoie zéro.

(7)

Autrement, retours le metatable de l'objet donné.

Infos sur la mémoire (gcinfo)

gcinfo()

Retourne deux résultats : le nombre de K bytes de mémoire dynamique que Lua emploie et le seuil courant de collecteur de mémoire (aussi en K bytes).

Itération sur table ipairs(t)

ipairs(t)

Renvoie 3 valeurs : une fonction d'iteration, la table t, et 0, de sorte que la construction: for i,v in ipairs(t) do ... end

réitère sur les pairs (1, t[1 ]), (2, t[2 ])..., jusqu'à la première clef (nombre entier) avec une valeur de zéro dans la table.

Chargement d'un fichier comme code (loadfile)

loadfile(filename)

Charge un fichier filename comme chaîne de caractères de code (fontion) . S'il n'y a aucune erreur, le retour peu être une fonction ;

Sinon retourne nil avec un message d'erreur.

L'environnement de la fonction retournée est l'environnement global.

Chargement d'une librarie LUA (loadlib)

loadlib(libname, funcname)

Cette fonction lie le programme LUA avec la bibliothèque dynamique C "libname".

À l'intérieur de cette bibliothèque, elle recherche une fonction "funcname" et renvoie cette fonction comme fonction de C. libname doit être le nom de fichier complet de la

bibliothèque de C, y compris n'importe son chemin d'accès.

Cette fonction ne supporte pas la norme ANSI C. En tant que tels, elle est seulement disponible sur quelques plateformes (Windows, Linux, Solaris, plus d'autres systèmes d'Unix qui soutiennent la norme de dlfcn).

loadlib vous donne la capacité d'augmenter vos fonctions native lua avec des fonctions de C écrites par encapsulation. L'exemple suivant devrait vous donner quelques conseils si vous voulez créer vos propre fonctions native LUA. Cet exemple fonctionne sous linux mais devrait aussi fonctionner avec d'autres plateformesi.

Tous les fichiers dans l'exemple devraient être dans le même répertoire. / * mylib.c pourrait ressembler à ceci : */

# include "lua.h"

(8)

lua_myfunc(lua_State interne statique * l) {

printf("blabla") ; retour 0 ;

} /* cette fonction est notre initialisation */ init(lua_State interne * l)

{

fonctions personnelles printf("Registering") ;

lua_register(l, "myfunc", lua_myfunc) ; printf("Done s'enregistrant") ;

retour 0 ; }

Compilez le maintenant le comme librairie (dll sous windows)

Après que ceci vous devrait avoir un dossier appelé mylib.a, c'est notre bibliothèque. Laisse maintenant écrire un manuscrit simple d'essai dans le lua :

luainit = loadlib("./mylib.a", "init") -- appelez maintenant la fonction enregistrée par print("New de luainit() de routine d'initialisation : ".. myfunc) -- commencez le nouveau print("well de myfunc() de fonction fait.")

Chargement d'une chaine de caractères à partir d'un fichier

(loadstring)

loadstring(string [, chunkname ])

TODO : Charge une corde comme gros morceau de Lua (sans le courir). S'il n'y a aucune erreur, des retours le gros morceau compilé comme fonction ; autrement, zéro de retours plus le message d'erreur. L'environnement de la fonction retournée est l'environnement global. Le chunkname facultatif de paramètre est le nom à employer dans des messages d'erreur et corrige l'information.

Balayage d'une table (next)

next(table [, index ])

Permet à un programme de parcouri tous les champs d'une table.

Le premier argument est une table et le deuxième argument est un index dans cette table, la fonction retourne le prochain index de la table et la valeur liées à cette index.

Si la fonction est appelée avec nil en tant que deuxième argument, la fonction retourne le premier index de la table et sa valeur associée.

Si la fonction est appelée avec le dernier index, ou avec nil dans une table vide, la fonction retourne nil.

Si le deuxième argument est absent, alors il est interprété comme nil.

Lua n'a aucune déclaration de champs ; Il n'y a aucune différence entre un champ non existant dans une table ou un champ avec une valeur nil. Par conséquent, la fonction considère seulement des champs avec des valeurs de non nil.

L'ordre dans lequel les index sont énumérés n'est pas indiqué, même pour des index numériques. (pour parcourir une table dans l'ordre numérique, employez un index numérique pour ou la fonction ipairs fonctionnent.)

(9)

Obtenir une paire clé valeur (pairs)

pairs(t)

Renvoie la prochaine fonction et la table t (ou nil), exemple :

for k,v in pairs(t) do ... end --Appel de fonction en mode protégé (pcall) pcall(f, arg1, arg2...)

Appelle la fonction f avec ses arguments en mode protégé. Cela signifie qu'aucune erreur à l'intérieur de f n'est propagée ; au lieu de cela, le pcall décèle l'erreur et renvoie un code de statut.

Son premier résultat est le code de statut (un booléen), qui est vrai si l'appel réussit sans erreur.

Dans un tel cas, le pcall renvoie également tous les résultats de l'appel, après ce premier résultat.

En cas de n'importe quelle erreur, le pcall renvoie faux plus le message d'erreur.

Impression vers la sortie standard (print)

print(e1, e2...)

print imprime les valeurs séparées par des virgule vers la sortie standard stdout. print ne nécessite pas l'utilisation de tostring pour la conversion des chaînes de caractères pour être imprimées. Par exemple:

print(1,2, "bouclent ma chaussure", 22/7) 1 2 bouclent ma chaussure 3.1428571428571

print est très simple et ne peut parcourir des tables en imprimant leur contenu, il imprimera juste le type et une identification unique.

> table={1,2,3} >print(table) 002FE9C8

print ne compose pas le texte. Afin de faire ceci vous devez employer la

fonction string.format() en même temps que print (voir le StringLibraryTutorial) par exemple:

> print(string.format("Pi est approximativement %.4f", 22/7)) pi est approximativement 3.1429

Test d'égalité (rawequal)

rawequal(v1, v2)

Vérifie si v1 est égal à v2, sans appeler de metamethode. Renvoie un booléen. Test d'égalité (rawget)

(10)

Obtenir la valeur brute d'un champ de table (rawget)

rawget(table, index)

Obtient la valeur réelle de table[index ], sans appeler de metamethode. table doit être une table, l'index est n'importe quelle valeur différente de zéro.

Définir la valeur brute d'un champ de table (rawset)

rawset(table, index, valeur)

Place la valeur réelle dans table[index ] , sans appeler de metamethod.

table doit être une table, l'index est n'importe quelle valeur différente de zéro, et la valeur est n'importe quelle valeur de Lua.

Chargement d'un package(require)

require(packagename)

Charge le paquet donné. La fonction commence par regarder dans la table _LOADED pour déterminer si le packagename est déjà chargé.

Si il l'est, il demande en retour la valeur que le paquet a renvoyée quand il a été chargé la première fois. Autrement, il recherche un chemin pour le charger.

Positionne l'environnement (setfenv)

setfenv(f, table)

Place l'environnement courant à employer par la fonction donnée.

f peut être une fonction de Lua ou un nombre, nombre qui indique la fonction à ce niveau de pile :

Le niveau 1 est la fonction appelle le setfenv.

Défini une metatable associé à une table (setmetatable)

setmetatable(table, metatable)

Place le metatable pour la table donnée. (vous ne pouvez pas changer le metatable d'un userdata de Lua.)

Si metatable est nil, enlève le metatable de la table indiquée.

Si la metatable originale a un champ "__metatable", cela génère une erreur.

Conversion en valeur numérique (tonumber)

tonumber(e [, base ])

Essaye de convertir l'argument e en nombre. Si l'argument est déjà un nombre ou une chaîne de caractère représentant un nombre, alors la fonction tonumber renvoie ce nombre ; autrement, il renvoie nil.

(11)

Un argument facultatif indique la base pour interpréter le numéro. La base peut être n'importe quel nombre entier entre 2 et 36, inclus. Dans les bases au-dessus de 10: la lettre A (en majuscule ou minuscule) représente 10,

la lettre B représente 11, et ainsi de suite, ainsi la lettre Z représentant 35.

Dans la base 10 (le défaut), le nombre peut avoir une partie décimale, ainsi qu'un

exposant. Dans d'autres bases, seulement des nombres entiers non signés sont acceptés. exmple: >tonumber("10",2) 2 >tonumber("F",16) 15 tonumber("01010111",2) 87

Conversion en chaîne de caractères (tostring)

tostring(e)

Reçoit un argument de n'importe quel type et le convertit en chaîne de caractères dans un format raisonnable.

Pour un contrôle complet de la conversion de nombre en chaîne de caractères se référer à la fonction stringformat.

Si la metatable de e a un champ "__tostring_, tostring appelle la valeur correspondante avec e comme argument, et emploie le résultat de l'appel en tant que son résultat. tostring convertit son argument (juste son premier argument s'il y a en plus d'un) en chaîne de caractères.

print peut être employé avec tostring. Des valeurs simples (nombres, chaînes de caractères , booleans, et zéro) sont converties comme vous le souhiatez. Des Table, Userdata, et les fils, sont imprimés comme table de ` : ', userdata de ` : ', ou fil de ` : ', suivi de l'adresse d'un objet interne d'interprète (qui devrait dans aucun cas être compté au moment).

Notez que contrairement à print, tostring n'imprime rien, il convertit juste son argument à une chaîne de caractères et retourne la valeur.

tostring le 'comportement de s est extensible. Si la valeur à convertir a un metatable avec une entrée __tostring puis que l'entrée s'appelle avec la valeur à convertir et le résultat de cet appel est retourné. Ceci vous permet de changer

comment tostring analyse (certaines) tables, en leur donnant un metatable avec une fonction __tostring qui exécute la conversion que vous voulez.

Connaitre le type d'une variable (type)

(12)

type renvoie une chaîne de caractères décrivant le type de l'objet fourni. > type(1) 'number' >type(true) 'boolean' >type("hello") 'string' > type({}) 'table'

La note, le type de nil est "nil". >type(nil)

'nil'

Les types possibles retournés dans Lua 5.0 sont : "number", "string", "boolea," table "," function "," fil ", et "userdata ". Un "fil" est une coroutine, et "userdata" est un type de données de C avec une référence propre dans Lua.

Affiche le contenu d'une liste (unpack)

unpack(list)

unpack prend les éléments d'une liste et les renvoie, par exemple : > = unpack({1,2,3}) 1 2 3 > = unpack({"one", 2, 6*7}) one 2 42

Le nombre d'éléments affiché est défini par la taille de la table, qui n'est pas nécessairement le nombre d'éléments dans la table !

> t = {"one", 2, 6*7} > t.n = 2 > = table.getn(t) 2 > = unpack(t) one 2

Affiche la version de LUA (_VERSION)

_ VERSION

Directement de du manuel, _VERSION est "une variable globale (pas une fonction) cette des prises une corde contenant la version courante d'interprète."

> = _ VERSION 'Lua 5.1'

(13)

le xpcall(f, errent)

Cette fonction est semblable au pcall, sauf que vous pouvez définir une nouvelle fonction errent de traitement des erreurs en mode protégé . Aucune erreur à l'intérieur de f n'est propagée ; au lieu de cela, le xpcall décèle l'erreur, appelle la fonction d'exception avec l'erreur d'origine, et renvoie une chaîne de caractères comme code de statut.

Son premier résultat est le code de statut (un booléen), qui est vrai si l'appel de fonction réussit sans erreurs. Dans un tel cas, le xpcall renvoie également tous les résultats de l'appel, après ce premier résultat. Pour toutes les autres erreurs, xpcall renvoie false plus le résultat de errent.

Références

Documents relatifs

Et s’il eût seulement nombré jusqu’à trente ou quarante retours de l’une tirée vingt degrés ou moins, et de l’autre quatre-vingts ou nonante degrés, il est connu que la

Dans le cas où le nombre de mesures est très grand, et que l’on s’approche d’une distribution normale, les valeurs extrêmes ne constituent plus une bonne approximation

On désire ecrire un programme qui calcule le discriminant et les éventuelles racines d’un trinôme du second degré ax 2 + bx + c... Première S Programmer

34 Toujours concernant cette situation « cet événement de vie » et cette administration « l’administration avec laquelle vous avez été principalement en contact »,

Une expression complète du résultat du mesurage comprend donc des informations sur l’incertitude de mesure qui permet d’indiquer quel est l’intervalle des

véritablement l’erreur commise lors d’un calcul éléments finis et ceci pour un grand nombre d’applications.... Où

La moyenne harmonique serait donc supérieure , ce qui est impossible avec des nombres strictement positifs : Puce a effectivement fait une erreur de calcul.. A2826 - Une erreur

Mais on remarque que la moyenne arithmétique des réels choisis par Puce (159/47 = 3,383) est inférieure à leur moyenne harmonique (47/13 = 3,615), ce qui est