| Ravi Welcome Documentation Documentation About Ravi Documentation Introduction Premiers pas avec Ravi ravitool Scheme Tutorial Objets Scheme Le shell ravi Starting Ravi Le module trace Les ports d'E/S The C Parser load, require, modules Système d'interruptions Scheme compiler C++ mode Generating C++ Modules La déclaration struct Le type "C-object" More information Installation | load, require, modules
On trouve sur cette page: La fonction load sert à charger un fichier. Dans le cas le plus simple, c'est un fichier avec des définitions des fonctions Scheme; il suffit de taper pour que monfichier.scm soit ainsi chargé - le load est capable d'ajouter le bon suffix. Détail important: dans quel répertoire trouve-t-on ce fichier? Le load cherche dans les répertoires donnés par la variable Unix RAVI_DLD_PATH; il est important que celle-ci inclut le répertoire courant ./ La fonction include: include est synonyme de load pour des programmes interprétés. Par contre, include est traité très différemment par le compilateur. Voir la doc du compilateur. Lorsqu'on avance dans un projet de programmation, on exige plus d'une fonction de chargement - en effet, la fonction load est capable de beaucoup de choses qu'on prendra la patience à expliquer.
Le load a 3 paramètres: dont seul le premier est obligatoire: une chaine s. Dans le cas le plus simple, s est le nom d'un fichier qu'on charge. Plus généralement, le load procède en trois étapes:
1 Analyse de l'argument sCette analyse fournit trois chaines de caractères:
2 Recherche de fichierOn balaie une liste de répertoires Dir-List à la recherche d'un fichier Nom.su Le suffixe su est le Suf déterminé au 1, s'il existe; sinon, il doit être dans la liste des suffixes standards: .mobj .scm .o .so (cf. Init.scm) La Dir-List et déterminée en fonction du préfixe Dir, du parametre path-l, et de la variable globale *ld-path* comme suit. * Si au 1 on a trouvé un préfixe Dir non vide, on cherche seulement dans le répertoire ainsi défini: soit en absolu, si le 1ier caractère de Dir est / soit en relatif, par rapport au répertoire . (Question: meme si dans un load recursif?) * Sinon, si l'appel du load comporte un parametre path-l explicite, c'est la Dir-List. (path-l doit être une liste pour être pris en compte). * Sinon, si le load est appelé au "premier niveau", la Dir-List est donnée par la variable *ld-path*, qui, normalement, dérive de la variable Unix RAVI_DLD_PATH (cf. Init.scm). Attention: en principe, RAVI_DLD_PATH doit commencer par un . * Si le load a été appelé, récursivement, à l'intérieur d'un load, la Dir-List commence par le répertoire courant, puis la variable *ld-path*. C'est une forme de liaison lexicale de fichier qui assure une bonne transparence, mais que ne colle pas avec l'esprit Unix. Si aucun fichier convenable n'est trouvé lors de la recherche, on appèle la fonction err-fn, si load a été appelé avec un 3ieme paramètre. err-fn doit être une fonction sans arguments. Si ce 3ieme parametre n'est pas fourni, on provoque une erreur. Remarques 1) C'est la variable *current-load-path* qui indique au load ou il en est. Il me semble raisonnable de mettre (set! *current-load-path* "") dans votre .RaviInit.scm - comme c'est deja fait dans Init.scm Sans quoi un load dans le fichier init peut ne pas fonctionner! 2) Le load-once a exactement les mêmes paramètres. La seule différence: il charge le fichier seulement si le nom extrait de l'argument s ne figure pas dans la liste des modules chargés. (variable *features*) 3) Le paramètre path-l est pris en compte seulement s'il est une liste non vide, (ca doit évidemment être une liste de chaines de caractères). On peut donc fournir une fonction err-fn sans imposer de Dir-List. 3 Chargement a proprement parlerEn mode verbose, un message est imprimé avec le nom complet du fichier. ======================================================================
Où la fonction require trouve-t-elle un module? Désormais, le require effectue une recherche dans un certain nombre de répertoires. C'est un changement majeur par rapport au passé, où on utilisait une table qui listait tous les modules, table initialisée par appels à la fonction register-module; cette fonction disparait, ainsi que la table au nom de *modules*. C'est un changement important qui devrait simplifier la vie à tout le monde! Fonctions(require nom) La fonction require recherche, dans une liste de répertoires, le premier fichier nom.suffixe ; le suffixe étant un parmi .x.scm .mobj .scm .so {ou .o sur SunOS4}. La liste de répertoires par défaut dépend de la variable système RAVIREP: ("$RAVIREP/Module" "$RAVIREP/Module/$RAVIARCH" "$RAVIREP/Module/GenModule" "$RAVIREP/Runtime") Si ce défaut n'est pas suffisant, il faut utiliser une variable système au nom de RAVI_MOD_PATH; le défaut est équivalent à setenv RAVI_MOD_PATH $RAVIREP/Module"':'"$RAVIREP/Module/$RAVIARCH"\ ':'"$RAVIREP/Module/GenModule"':'"$RAVIREP/Runtime La liste des répertoires utilisée par require se trouve dans la variable globale *module-path* qui est initialisée dans le Init.scm. (locate-module nom sl) Cherche le fichier d'un module, avec un des suffixes de la liste sl; résultat #f si pas trouvé, sinon c'est la liste (dir name suffix fullname) (calcule-path2 var défaut) devrait remplacer calcule-path La fonction permet de faire face au cas où nom de module et nom de fichier divergent; on cherchera à éliminer ce cas. =============================================
Un "truc" simple et elégant à connaitre, notamment pour les fichiers d'initialisation (.RaviInit.scm notamment): la définition qui effectue un chargement ou autre au premier appel, et qui disparait aussitot après. Prenons des exemples dans Init.scm, pour voir deux versions: Première version: fonction normale
Deuxième version: avec macro
Lors du premier appel de trace, le (require 'trace)effectue les initialisations necéssaires, puis la macro provoque un nouvel appel de la trace, avec les mêmes arguments; la définition qui vient d'être chargée est alors trouvée et s'exécute normalement. C'est astucieux pour plusieurs raisons:
C'est intéressant pour les modules qui ont 1 ou 2 fonctions principales. Notez le nombre d'arguments variables: cela permet tout nombre d'arguments dans la définition définitive. La première version semble préférable: les macros ne font pas partie de la définition de Scheme, et on peut compiler des appels de pretty-print sans pb, ce qui n'est pas le cas pour la macro. Attention: si, par erreur, la require ne (re-)définissait pas la fonction trace, il y aurait une boucle infinie. Ce type de définition est utilisé (dans le fichier Init.scm) pour: pretty-print trace silent-trace help a-propos defrule assert .
Nous appelons "boite à outils" un ensemble de modules interdépendants (ou non), qui peuvent faire appel à des fichiers auxiliaires. Ce paragraphe décrit un schéma d'installation standard que nous proposons. Schéma facile à adapter. Principe: les modules, au sens Ravi, résident dans un répertoire. Ce répertoire figure dans la variable *module*. Aucun fichier auxiliaire ne se trouve dans ce répertoire (cela évite der erreurs), mais dans des sous-répertoires. Cela assure qu'on peut facilement déplacer une boite complète, et qu'on trouvera toujours les bons fichiers auxiliaires! Trois variables Ravi permettent de paramétrer tout cela: *module-path*, *ld-path*, *roo-load-path*.Elles sont définies dans le fichier ~/.ravi/paths.scm Par ailleurs, il faut que le LD_LIBRARY_PATH soit correctement défini pour les chargement via Ravi (rien n'a changé sur ce point). *module-path* *ld-path* *roo-load-path*Cette variable est utilisée pour charger les .sodepuis un fichier Scheme: elle donne une liste de répertoires en relatif!C'est nouveau - ce petit point est important! Remarque: si la variable *roo-load-path* a pour valeur #f, on retombe dans la convention ancienne, selon laquelle les .so sont cherchés dans les répertoires de *ld-path*. Exemple: la boite à outils libvision. Mon fichier ~/.ravi/paths.scm est comme suit: (la fonction dir-name traduit les variables Unix, elle a été ajoutée dans Init.scm)
============================================== A discuter: nous avons 2 noms d'architecture: RAVIARCH et *system-architecture* |