Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

what means the m. in front of a variable? 3

Status
Not open for further replies.

Paco75

Programmer
Oct 11, 2001
239
US
Hi,

I have seen some m.variable things in some code... why is there a m. before? Im asking because i got an bug in a case where a field from a table has the same name than a m. variable...

let's say i got mytable.myfield and m.myfield and if i do Vartype(myfield) to verify the mytable.myfield and it seems to do it on m.myfield instead.

thanks
 
The m. is part of the OLD FP syntax which designates a Memory variable as opposed to a Table Field.

In some ways that syntax is consistent with the current Table Field syntax where the Table Alias is followed by a '.' and then the Field Name

Example: MyTable.Customer && Customer Field in data table MyTable

BUT the m., while seen in OLD code, is not used much any more.

While individuals might continue to use their own 'flavor' of syntax, you can find a pretty well explained Naming Convention for Memory Variables at:

Good Luck,
JRB-Bldr
 
m. simply means the memory variable of that name. Unless you specify an alias (as in xyz.variable) vfp will use m.variable if it exists.

except commands like

variable = date()

which will ALWAYS change (or create) the memory variable of that name (you'd need to use the REPLACE command to affect the table field)

Many people (myself included) prefer to always explicitly use m. in their code even when it is redundant.

e.g.
m.variable = date()

Others hate seeing it and will remove it wherever they find it.


it largely dates back to when it was standard practice to SCATTER MEMVAR... thereby creating memory variables for each field in a table. With buffering and/or SCATTER NAME in more recent versions scatter memvar is frowned upon.


hth

nigel


 
actually here's is the code that goes wrong.

Code:
IF VARTYPE(Autre) != "U" THEN
	REPLACE G_Autre WITH Autre
	ALTER TABLE DBF() DROP COLUMN Autre
ENDIF

i want to verify if the table field named autre exists. But because of the m.autre that exists it goes inside the IF and tries to drop a column in the table but it does not exist! is there a way to remove m.autre? i mean i can simply remove variable from memory when i quit a form.
 
by removing variable i mean doing the opposite of PUBLIC m.autre

the public variable is declared on init of a subform but when the sub form is closed it is no more used. So if i could "UNDECLARE" it it should be fine.
 
REPLACE G_Autre WITH Autre

The reason to use SOME prefix as part of a memory variable name is to clearly differentiate between a Field Name and a Memory Variable.
Especially in the situation where a Field and a Memory Variable have the EXACT same name - a BAD practice.

The following would be clear in their meaning:
REPLACE G_Autre WITH m.Autre
REPLACE G_Autre WITH lcAutre
REPLACE G_Autre WITH gdAutre


Boris - what part is 'not quite right' ?
From the link you referenced:
to prefix the variable name with “m.” which specifies that the name is *not* a field name, but a variable. This boosts performance, even if there is a table with many fields open.

Restated: if you have VFP code that accesses a variable with a syntax that *could* be a field reference, and there is a possibility that a cursor is open in the current workarea as well, preface that variable with “m.” for better performance. VFP then “knows” that it can’t be a field name.


That seems consistent with what I said even though it was written back on 14 Dec 2004

Calvin talks of 'better performance' through using the 'm.', but I am not sure if using the 'm.' results in any REAL better performance than using the newer syntax 'standards'.

Paco - Good Luck,
JRB-Bldr

 
Paco

try

if fsize('autre') > 0
REPLACE G_Autre WITH Autre
ALTER TABLE DBF() DROP COLUMN Autre
ENDIF


n
 
BUT the m., while seen in OLD code, is not used much any more.

But it is still a vital part of properly scoping variable names when confusion between an object or alias may occur.

Code:
a = Createobject("Form")
* this scope confuses the interpreter
a.Show  && error!
* this statement is properly scoped
m.a.Show  && success!

It might not be used in cases where naming conventions obviate the need WRT field names, but that's just a convention (or coincidence). The language still requires the construct in some cases, such as when using scatter/gather.
 
Paco,

The help has very few words on it:
...You can reference the variable using m. or m-> plus the variable name...

The only place - I think - this is ever mentioned in the vfp help.

What's more important:
If a variable has the same name as a field, Visual FoxPro always gives precedence to the field name.

Once you know you can adress a table field by it's name only, and you know a field name has the same naming rules as a variable name (starting with letter or _, etc etc), you actually already know there could be that precedence conflict.

The question what IS adressed, if both a variable and field of the same name exist, should come to any vfp developers mind, anyway, once you knwo you can adress a field of the selected workarea by the field name only. But don't be ashamed, it's something most developers will not think about, even if they work with foxpro for quite some time.

The typical and more dangerous m. problem is to read a table field, where you wanted to access a variable. But that's not your problem here. You WANT to adress the field instead of the variable. What is byting you is, that a variable name does not NEED to be adressed via m., but you are surely aware of that, as you also did use variables before, or didn't you?

So you actually did know that this could also adress a variable, if that field was not present. Just by the name of vartype() you know it's quite clear it was initially meant for variables. You know you can also check for fields, but you also are aware, this could also check for a variable, don't you? It's not called fieldtype(), is it? And so not knowing about m. does not explain, why you fell into that trap.

I used VARTYPE() in db update scripts, too, but VARTYPE(tablename.fieldname). Doesn't this sound much more concrete? In fact it can also fail with an object having the same name as a table, but the environment of an update script is limited, it's the only thing started.

So, you ask yourself where the variable comes from? Most probably by scatter memvar. And that is a thing of the past, when you bound controls to variables. It was replaced by buffering quite some time ago, still people use scattering and do create variables in an uncontrollable manner. There is SCATTER NAME to keep that encapsulated in one object variable, just don't fall for nameing that object like the table...

Actually, the ultimate way to check for fields would rather be AFIELDS() or looping FIELD(n) from 1 to FCOUNT() or using dbgetprop(). I would rather opt for adressing fields including the alias at any time! And so I'd opt for RELEASE (ALIAS()) and checking Type(Alias()+".Autre"). Check out the difference of Type() vs Vartype() to understand why you can work with Alias() here and need to put the field name into quotes.

Be verbose in your code, eg adressing alias.fieldname to adress a field, using the IN alias clause instead of depending on the correct alias being the active workarea. Always.

The other problem with m. is performance. As vfp checks for a field of that name first, an active workarea with many fields can slow down variable access. It seldom has a big effect, only in loops with many iterations. The clean way is to always adress variables with m., another way is to SELECT 0 before chewing on variables. You could also use arrays for all variables, always adressing variablename(1). Actually nothing, that would save you from your case, you just were not verbose enough.

Bye, Olaf.
 
Paco,

the public variable is declared on init of a subform but when the sub form is closed it is no more used. So if i could "UNDECLARE" it it should be fine.

The command you are looking for is RELEASE.

So to "undeclare" a memory variable named Autre, you do this:

Code:
RELEASE Autre

I think there was some confusion between variables and fields. Your ALTER TABLE code will remove a field named Autre. That's quite different from removing a memory variable.

Mike



__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips, training, consultancy
 
It's likely RELEASE Autre would solve that problem but raise a new one elsewhere, because variables seldom exist by accident, so it normally is used and needed, most probable in code folowing or code calling this code, if it's a private variable...

I'd strongly consider using Type(Alias()+".Autre") or even going for AFIELDS(), then ASCANning for the field name in the resulting array. If you want a clean check for the existance of a table field.

Bye, Olaf.
 
Yes, Olaf is right. In fact, I'd go one step further and ask why this is a public variable in the first place.

Give the variable is created in the Init of a form, and is not required in a subsidiary form, it looks like it should be property of the (first) form rather than a variable. That would be a much better approach.

MIke


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips, training, consultancy
 
I bet it's a variable created by scatter. such variables are created public, at least when doing in the command window and then list memory to somefile you can see they are listed as Pub(lic).

Besides: the help topic on SCATTER has a reference to the m. qualifier in the memvar section.

Bye, Olaf.
 
Thanks to all for the answers.

The variable is in the init of a subsidiary form as Mike said. Its a form i am reusing somewhere in my code (a form i did not coded and exist since a long time). In the light of your explanations i should be able to get out of the pitt.

Thanks again for educating me on foxpro! :)
 
Hi,

dont ever think of the m. as a prefix it is an objectdeclaration.

lcMyVariable in this case lc is a prefix
m.lcName m is an objectdeclaration, the object type is variable

Coding with m. is not old fashioned! and is also not justified because it is faster than without it is an absolute must for generic coding.

Regards,

Jockey(2)
 
Jockey,

With the greatest of respect, I think you are only adding to Paco's confusion when you describe m. as an object declaration. Whatever your basis for saying that, it can only make it more difficult to understand the concept.

Also, it's perfectly legitimate to call m. a prefix. Just because lc (for example) is also a prefix, it doesn't mean that you can't use that same term for m. A prefix is something that is added to the beginning of a word, and both m. and lc qualify for that.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips, training, consultancy
 
I agree to Mike in general, prefix is a term not only valid for naming convention prefixes, but it is often meant as such.

For the sake of clarity we could take the term MS used in the help and name m. a memory variable qualifier.

And actually m is a very special object, if you talk of it as such anyway. Generic object, Inherent object, I don't know how I'd call it, but just for fun do m = Createobject("custom"), Now typing m. in the command window will show m in a dropdown list. Actually now you are forced to use m.m.name to qualify the custom object namend m, because m is reserved for the memory "object". So m.name results in an error, the variable "name" does not exist. m.m.name will work, but m.m. will not show the members of the custom object, intellisense is "confused", so to say.

Bye, Olaf.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top