Salut à tou(tes),
Je me lance un peu tardivement dans la création de mon premier module et j'ai une question sur la portée des variables utilisées à l'intérieur de ce module.
En préambule, je vais expliquer pourquoi je souhaite me tourner, à tort où à raison, vers un module.
J'ai jusqu'à maintenant un code utilisé en Include par plusieurs sources.
Ces sources récupèrent quelques données à partir de ce fichier inclus qui, lui, stocke en variables globales un très grand nombre de données sous forme de listes et de maps, structurées ou non. Ces listes et maps doivent être stockées en Global pcq utilisées par plusieurs procédures dans le fichier inclus.
J'utilise donc une variable structurée globale que j'alimente en picorant, ici et là, des données dans ces listes et maps et que je récupère dans les sources appelants.
Le souci, c'est que toutes ces variables globales (ainsi que certaines structures) restent disponibles dans ces sources, ce dont je n'ai plus besoin puisqu'elles ne sont utiles que temporairement.
D'où mon idée du recours à un module.
En effet, dans la doc, il est indiqué dans l'exemple, que ce qui est déclaré dans DeclareModule est accessible à l'extérieur (donc global à l'ensemble du source) et que ce qui est déclaré à l'intérieur de Module est inaccessible à l'extérieur (donc local au module), hormis bien évidemment ce qui a été précédemment déclaré dans DeclareModule.
Je pensais donc trouver ici la réponse à mon objectif premier, à savoir que toutes mes déclarations globales dans le module resteraient locales dans ce module et ne serait plus accessibles une fois un UnuseModule appelé.
Mais, hélas, ce n'est pas le cas. Après tests sur mes sources et même de modules créés par d'autres, je constate que les variables déclarées en global dans le module restent en mémoire même une fois UnuseModule employé.
J'ai donc dû me méprendre sur le fonctionnement des portées à l'intérieur des modules (déclarées dans Module) et la fonction d'UnuseModule.
Ce dernier sert à quoi donc ? Il est indiqué qu'il retire les éléments du module, mais qu'est-il entendu par éléments ? Sert-il uniquement à éviter l'appel direct aux procédures, etc déclarées dans DeclareModule et obliger l'emploi de "NomDuModule::xxxxx()" ?
Y a-t-il un moyen de faire fonctionner un module comme une procédure, c'est-à-dire qu'une fois son utilisation terminée, il libère automatiquement les ressources qu'il a créées ou dois-je créer une autre procédure à l'intérieur qui les libèrera avec des FreeList, FreeMap, etc. ?
Merci pour vos réponses.
[CLOS] Question sur les modules
-
- Messages : 604
- Inscription : lun. 26/avr./2010 16:14
- Localisation : S 48° 52' 31'' / O 123° 23' 33''
[CLOS] Question sur les modules
Dernière modification par boddhi le sam. 16/mars/2024 13:24, modifié 2 fois.
-
- Messages : 604
- Inscription : lun. 26/avr./2010 16:14
- Localisation : S 48° 52' 31'' / O 123° 23' 33''
Question sur les modules
J'ai testé aussi avec des Define, en lieu et place des Global, avec des Shared dans les procédures locales du module mais même résultat : Les données listes et map restent dispos dans le source appelant...
Re: Question sur les modules
Il nous faut un peu de code exemple, 1 pour le module et 1 pour le source appelant.
M.
M.
-
- Messages : 604
- Inscription : lun. 26/avr./2010 16:14
- Localisation : S 48° 52' 31'' / O 123° 23' 33''
Re: Question sur les modules
Salut Mesa,
Poster ce dernier en entier serait très long (il faudrait une 10aine de messages pour ce faire) et l'expurger aurait été bien plus éreintant
Donc, comme écrit dans les commentaires, j'aurais pensé que les variables globales déclarées à l'intérieur du module disparaissaient une fois le module "déchargé" avec UnuseModule comme c'est le cas, par exemple, avec les procédures. Une fois sorti d'une procédure, toutes les variables déclarées à l'intérieur sont libérées de la mémoire.
Alors, en effet, les variables locales ne sont plus accessibles à l'extérieur. Un
génèrera une erreur mais néanmoins elle restent stockées en mémoire.
Mon souci, dans mon code, c'est que je stocke dans le module énormément de données par le biais de listes, maps, etc. dont je n'ai plus besoin une fois sorti du module.
J'ai dû me méprendre sur la fonction d'UnuseModule dont l'explication comportementale dans la doc est abusivement très très laconique
J'ai donc fini par créer une procédure, à l'intérieur du module et déclarée dans DeclareModule, que j'appelle dans le source principal avant UnuseModule et qui libère (via des FreeXXXX()) toutes ces données,
Espérant avoir été clair dans mes explications.
Ici, un exemple très très simplifié de l'esprit de mon code originel.Mesa a écrit : Il nous faut un peu de code exemple, 1 pour le module et 1 pour le source appelant.
Poster ce dernier en entier serait très long (il faudrait une 10aine de messages pour ce faire) et l'expurger aurait été bien plus éreintant

Code : Tout sélectionner
EnableExplicit
DeclareModule TEST
Structure STRUCTUREGLOBALE
VariableG1.a
VariableG2.s
VariableG3.u[4]
List VariableG4.l()
EndStructure
Global.STRUCTUREGLOBALE VariableG
Declare Pc_ProcedureGlobale()
EndDeclareModule
Module TEST
Structure STRUCTURELOCALE
VariableL1.s
VariableL2.a
VariableL3.q[4]
List VariableL4.l()
EndStructure
Global.STRUCTURELOCALE VariableL
Global NewList Liste.s()
AddElement(Liste()):Liste()="Element 1"
AddElement(Liste()):Liste()="Element 2"
Procedure Pc_ProcedureLocale()
VariableL\VariableL1="Test"
EndProcedure
Procedure Pc_ProcedureGlobale()
Pc_ProcedureLocale()
VariableG\VariableG2=VariableL\VariableL1
EndProcedure
EndModule
;
;
;
UseModule TEST
Debug "Valeur VariableG\VariableG2 avant : "+VariableG\VariableG2
Pc_ProcedureGlobale()
Debug "Valeur VariableG\VariableG2 après : "+VariableG\VariableG2
UnuseModule TEST
;
; Ici je m'attendais à ce que toutes les variables (variables structurées ou non, listes, etc) globales déclarées
; à l'intérieur du module disparaissent de la mémoire comme un peu ce qu'il se passe avec une procédure.
; Ce qui n'est pas le cas en explorant le visualisateur de variables.
ShowVariableViewer()
CallDebugger
;FirstElement(Liste()):Debug Liste()
Alors, en effet, les variables locales ne sont plus accessibles à l'extérieur. Un
Code : Tout sélectionner
FirstElement(Liste()):Debug Liste()
; ou un
Debug VariableL\VariableL1
Mon souci, dans mon code, c'est que je stocke dans le module énormément de données par le biais de listes, maps, etc. dont je n'ai plus besoin une fois sorti du module.
J'ai dû me méprendre sur la fonction d'UnuseModule dont l'explication comportementale dans la doc est abusivement très très laconique

J'ai donc fini par créer une procédure, à l'intérieur du module et déclarée dans DeclareModule, que j'appelle dans le source principal avant UnuseModule et qui libère (via des FreeXXXX()) toutes ces données,
Espérant avoir été clair dans mes explications.

Re: Question sur les modules
Les variables ne sont pas détruites donc elles restent accessibles au debugger, mais seulement lui, pas le reste du programme. Heureusement car ça permet de réutiliser un module même après un UnuseModule comme ci-dessous.
Tout fonctionne bien en fait.
M.
Tout fonctionne bien en fait.
M.
Code : Tout sélectionner
EnableExplicit
DeclareModule TEST
Structure STRUCTUREGLOBALE
VariableG1.a
VariableG2.s
VariableG3.u[4]
List VariableG4.l()
EndStructure
Global.STRUCTUREGLOBALE VariableG
Declare Pc_ProcedureGlobale()
Declare.s Get()
EndDeclareModule
Module TEST
Structure STRUCTURELOCALE
VariableL1.s
VariableL2.a
VariableL3.q[4]
List VariableL4.l()
EndStructure
Global.STRUCTURELOCALE VariableL
Global NewList Liste.s()
AddElement(Liste()):Liste()="Element 1"
AddElement(Liste()):Liste()="Element 2"
Procedure Pc_ProcedureLocale()
VariableL\VariableL1="Test"
EndProcedure
Procedure Pc_ProcedureGlobale()
Pc_ProcedureLocale()
VariableG\VariableG2=VariableL\VariableL1
EndProcedure
Procedure.s Get()
ProcedureReturn VariableG\VariableG2
EndProcedure
EndModule
;
;
;
UseModule TEST
Debug "Valeur VariableG\VariableG2 avant : "+VariableG\VariableG2
Pc_ProcedureGlobale()
Debug "Valeur VariableG\VariableG2 après : "+VariableG\VariableG2
UnuseModule TEST
;
; Ici je m'attendais à ce que toutes les variables (variables structurées ou non, listes, etc) globales déclarées
; à l'intérieur du module disparaissent de la mémoire comme un peu ce qu'il se passe avec une procédure.
; Ce qui n'est pas le cas en explorant le visualisateur de variables.
;=======================>>>>> VariableG n'est pas visible
Debug "Valeur VariableG\VariableG2 après : "+VariableG\VariableG2
; Debug TEST::Get(); accessible avec un getter, dans le module exclusivement.
; ShowVariableViewer()
; CallDebugger
;FirstElement(Liste()):Debug Liste()
-
- Messages : 604
- Inscription : lun. 26/avr./2010 16:14
- Localisation : S 48° 52' 31'' / O 123° 23' 33''
Re: Question sur les modules
Salut Mesa,
Et, entre-temps, j'ai fait quelques tests qui m'ont amené à confirmer la persistance des valeurs de variables déclarées à l'intérieur du module, globales ou non (pour ces dernières, bien-sûr, seulement si elles sont déclarées à la racine du module c-à-d hors procédures)
Et en conséquence, je confirme également la conclusion que j'avais soupçonnée qui était que si je veux décharger la mémoire de tous tableaux, listes, maps, variables, etc. après utilisation du module, je dois, selon le type, les réinitialiser ou les "libérer"...
Cet aspect-là a au moins mérite d'être clair maintenant !
Merci pour ta réponse.Mesa a écrit : Les variables ne sont pas détruites donc elles restent accessibles au debugger, mais seulement lui, pas le reste du programme.
Et, entre-temps, j'ai fait quelques tests qui m'ont amené à confirmer la persistance des valeurs de variables déclarées à l'intérieur du module, globales ou non (pour ces dernières, bien-sûr, seulement si elles sont déclarées à la racine du module c-à-d hors procédures)
Code : Tout sélectionner
EnableExplicit
DeclareModule TEST
Structure STRUCTUREGLOBALE
VariableG1.a
VariableG2.s
VariableG3.u[4]
List VariableG4.l()
EndStructure
Global.STRUCTUREGLOBALE VariableG
Declare Pc_ProcedureGlobale()
Declare.s Get()
EndDeclareModule
Module TEST
Structure STRUCTURELOCALE
VariableL1.s
VariableL2.a
VariableL3.q[4]
List VariableL4.l()
EndStructure
Global.STRUCTURELOCALE VariableL
Global NewList Liste.s()
Define.s VariableTexte
AddElement(Liste()):Liste()="Element 1"
AddElement(Liste()):Liste()="Element 2"
Procedure Pc_ProcedureLocale()
Shared.s VariableTexte
VariableTexte="Essai"
VariableL\VariableL1="Test"
EndProcedure
Procedure Pc_ProcedureGlobale()
Protected.s VariableProcedure
Shared.s VariableTexte
Debug "Valeurs variables avant assignation : "
Debug " VariableProcedure : "+VariableProcedure
Debug " VariableTexte : "+VariableTexte
Debug " VariableL\VariableL1 : "+VariableL\VariableL1
VariableProcedure="Valeur non persistante"
Pc_ProcedureLocale()
VariableG\VariableG2=VariableL\VariableL1
EndProcedure
Procedure.s Get()
ProcedureReturn VariableG\VariableG2
EndProcedure
EndModule
;
;
;
UseModule TEST
Debug "Valeur VariableG\VariableG2 avant procédure module : "+VariableG\VariableG2
Pc_ProcedureGlobale()
Debug "Valeur VariableG\VariableG2 après procédure module : "+VariableG\VariableG2
UnuseModule TEST
;
; Ici je m'attendais à ce que toutes les variables (variables structurées ou non, listes, etc) globales déclarées
; à l'intérieur du module disparaissent de la mémoire comme un peu ce qu'il se passe avec une procédure.
; Ce qui n'est pas le cas en explorant le visualisateur de variables.
;=======================>>>>> VariableG n'est pas visible
;Debug "Valeur VariableG\VariableG2 après : "+VariableG\VariableG2
Debug "UnuseModule"
Debug "---------------------------------------"
UseModule TEST
Debug "UseModule"
Debug "Valeur VariableG\VariableG2 avant réinitialsation : "+VariableG\VariableG2
VariableG\VariableG2=""
Debug "Valeur VariableG\VariableG2 après réinitialsation et avant procédure module : "+VariableG\VariableG2
Pc_ProcedureGlobale()
Debug "Valeur VariableG\VariableG2 après procédure module : "+VariableG\VariableG2
Et en conséquence, je confirme également la conclusion que j'avais soupçonnée qui était que si je veux décharger la mémoire de tous tableaux, listes, maps, variables, etc. après utilisation du module, je dois, selon le type, les réinitialiser ou les "libérer"...
Cet aspect-là a au moins mérite d'être clair maintenant !

