ATOUTFOX
COMMUNAUTÉ FRANCOPHONE DES PROFESSIONNELS FOXPRO
Visual FoxPro : le développement durable

Faut-il préfixer les variables par "m." ?   



L'auteur

Robert Plagnard
France France
Membre Simple
# 0000000031
enregistré le 15/10/2004

http://www.ingelog.fr
PLAGNARD Robert
75015 PARIS
de la société IngéLog
Fiche personnelle


Note des membres
pas de note

Contributions > 20 - Trucs et Astuces

Faut-il préfixer les variables par "m." ?
# 0000000116
ajouté le 03/12/2004 12:18:18 et modifié le 13/09/2006
consulté 10663 fois
Niveau initié

Description

Faut-il utiliser le préfixe « m. » devant les noms de variable? Eternelle question. Lorsque VFP rencontre dans une expression un nom qui peut être interprété comme une variable ou comme le champ d’une table, il résout l’ambiguïté en donnant priorité au champ de la table. Si l’objectif est de produire du code robuste, la réponse est évidemment OUI, il faut préfixer les variables par « m. » dans tous les cas où la variable est utilisée. Microsoft ne respecte pas toujours cette règle. Il est par exemple très facile de planter le Browser de classe. Pour vous en persuader tapez cette commande dans la fenêtre de commande :

create cursor CCC( tllistBox C(10))

 

 

puis  lancez le « Class Browser » à partir du menu de VFP vous obtiendrez l’erreur :

Function argument value, type or count is invalid

 

 

Pour comprendre ce qui se passe, décompressez xsource.zip qui se trouve dans le répertoire Tools, vous trouverez dans VFPSource\Browser\Browser.prg à la ligne 40 le code suivant :

IF tlListBox AND tlGallery

 

 

  MESSAGEBOX(M_LISTBOX_MODE_ERROR_LOC+".",48,M_COMPONENT_GALLERY_LOC)

 

 

 

Les variables (qui sont ici des paramètres de la procédure) ne sont pas préfixées par « m. », c’est le champ du cursor qui est pris. Il est de type caractère d’où l’erreur. S’il était de type logique l’erreur serait encore plus subtile car le programme serait faux sans déclencher d’erreur.

J’ai souvent lu du code où les programmeurs pensaient que pour les objets il n’était pas indispensable de les préfixer par « m. ». Le petit bout de code suivant devrait les persuader du contraire.   

 

 

create Cursor Art( Libelle C(50) )

 

 

insert into Art values( "Libellé de la Table" )

 

 

 

 

Art = CreateObject("CArt")

 

 

? Art.Libelle

 

 

? m.Art.Libelle

 

 

 

 

define class CArt as Custom

 

 

   Libelle = "Libellé de l'objet"

 

 

enddefine

 

 

 

Le résultat de ce morceau de code est :

Libellé de la Table

 

 

Libellé de l’objet

 

 

 

Ma règle est la suivante, lorsque la variable est déclarée ou affectée je ne met pas le préfixe (c’est moins lourd à taper) et lorsqu’elle est utilisée je le met (par obligation), par exemple :

 

local i

 

 

i = m.i + 1

 

 

for i = 1 to m.Limite

 

 

 

Si l’on remarque qu’il n’est pas possible de créer un champ dont le nom commence par « _ » on peut aussi utiliser des variables dont le nom commence par « _ » sans les préfixer par « m. » car l’ambiguïté n’est plus possible.

 

J’espère qu’il ne viendra à l’idée de personne d’appeler un objet m ! En fait cela est possible, exemple :

local nom

 

 

local m

 

 

nom = "Nom dans variable"

 

 

m = CreateObject( "MaClasse" )

 

 

 

 

? Nom

 

 

? m.Nom

 

 

? m.m.Nom

 

 

 

 

define class MaClasse as Custom

 

 

   nom = "Nom dans objet"

 

 

enddefine

Donne le résultat suivant :

Nom dans variable

 

 

Nom dans variable

 

 

Nom dans objet

 

 

En fait dans ce cas si l’on désire affecter une valeur à la propriété Nom de l’objet m il faut écrire :

m.m.Nom = "Nouveau Nom dans objet"

 

 

Tout autre écriture affecterait la variable Nom et non la propriété de l’objet m !

Il est à mettre au crédit de VFP que l’alias « M » est interdit. Sinon …

Mais l’alias « This » est parfaitement légal. Exemple :

create table THIS( X C(10))

 

 

insert into THIS values( "From Table" )

 

 

 

 

oSympa = CreateObject( "Sympa" )

 

 

? oSympa.F1()

 

 

? oSympa.F2()

 

 

 

 

define class Sympa as Custom

 

 

   X = "from Object"

 

 

  

 

 

   function F1

 

 

      return this.X  && syntaxe à risque

 

 

   endproc

 

 

  

 

 

   function F2

 

 

      return m.this.X  && syntaxe blindée

 

 

   endproc

 

 

 

 

enddefine

Donne le résultat suivant :

From Table

 

 

From Object

 

 

C’est la même chose avec « ThisForm ». Exemple :

create table thisform( X C(10))

 

 

insert into thisform values( "From Table" )

 

 

 

 

oSympa = CreateObject( "FormSympa" )

 

 

? oSympa.F1()

 

 

? oSympa.F2()

 

 

 

 

define class FormSympa as Form

 

 

   X = "from Object"

 

 

  

 

 

   function F1

 

 

      return thisform.X

 

 

   endproc

 

 

  

 

 

   function F2

 

 

      return m.thisform.X

 

 

   endproc

 

 

 

 

enddefine

Donne le même résultat que précédemment. Or dans les FFC « m. » n’est utilisé ni devant this ni devant thisform. On peut donc faire planter les FFC très facilement.

Pour terminer sur ce sujet inépuisable, il est vrai que si tout le monde utilise des conventions de dénomination stricte pour les champs, les variables et les objets, ces cas d’ambiguïté ne devraient pas se produire, mais peut-on appuyer une production de code robuste sur une telle hypothèse ? Je laisse la réponse au lecteur.

Commentaires
le 04/12/2004, Francis Faure a écrit :
Bonsoir Robert,

j'ai bien aimé ta réflexion sur ce sujet,
et les exemples sont clairs et complets,

je me permet : d'ajouter un peu d'eau à ta fontaine :

pour ma part :
- une variable préfixée d'un "_" est effectivement forcement une variable ,
mais je suggère : de ne pas de généraliser son emploi.
en effet il existe déjà des variables vfp de portée "public" / "globale" aux programmes codifiée sur cette forme. Leurs usages doivent être gardées à ce niveau me semble t il , donc une utilisation : trés modeste dans son ensemble.

- dans notre paroisse nous avons "conventionné" la chose suivante : toutes nos varibales sont préfixées de "v_" et il est interdit de créer un champ commençant par le même préfixe. De ce fait nous n'avons aucun problème. un peu de rigueur et la "liberté" que nous donne vfp est bien gérée.

- enfin tu ne parles pas de l'écriture elle même,
en effet il me semble important qu'un programme puisse être maintenu par plusieurs personnes, et donc puisse "re lire" clairement et sans ambiguité grâce de petite régles simples : aussi si les variables sont toujours préfixées "v_" (chez nous !!) les champs sont écrit en majuscules et de préférence avec le nom de l'alias. cela rend la lecture aisée et enlève les "doutes" de l'interpréteur vfp..
donc nous n'écrirons jamais :
for i=1 to 10
relace nombre with str(i)
abc = truc

...... mais

for v_i=1 to 10
replace NOMBRE with str(v_i)
v_abc = CLIENT.TRUC

la lisibilité des programmes est accrue, gain de temps...

Cordialement

Francis FAURE

le 09/05/2006, lotfi072003 a écrit :
Bravo, Mr
j'avait quelque remarque mais je l'ai retirer car je vois que l'experience qui parle
et chez nous lorsque les grand parle les enfants ecouts
tt mes respects chef
merci lotfi

le 25/02/2011, eddymaue a écrit :
Je ne suis pas d'accord avec Francis pour la simple raison que cette méthode de préfixation n'est pas claire sur la porté des variables dans l'ensemble d'un projet.

Voilà comment je procède

La première lettre est pour la porté
t= paramètre , p=Public , l=Local, g_=global et g=private

La seconde lettre assigne un type à la variable
c=caractère , l=logical, i=integer,n=numerique......

t pour paramètre et la seconde lettre pour son type
ex. : tcMaVariable
donc en lisant mon code je sais t = paramètre de fonction et de type caractère

l pour LOCAL et la seconde lettre pour son type
ex. : lcMaVariable
variable de porté local et type caractère

p pour publique
PiMavariable -- > p = public et i = integer

g_ pour global et donc définit en début et qui a une porté global sur l'ensemble du projet
gnMaVariable -- > g_ = global et n = numérique

g pour private
goMonObjet --> g pour private et o pour objet

les constantes de les définies comme suivants
C_MaConstante et ou C_ est caractère
I_MaConstante et ou I_ est integer
L_MaConstante et ou L_ est logique

et ainsi de suite

m. ou pas

avec ISX et intellisence assurément que j'utilise m. partout partout et partout

a+


www.atoutfox.org - Site de la Communauté Francophone des Professionnels FoxPro - v3.4.0 - © 2004-2024.
Cette page est générée par un composant COM+ développé en Visual FoxPro 9.0-SP2-HF3