Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Vartype with tables
Message
From
28/12/2007 09:52:07
 
 
To
25/12/2007 10:44:44
Metin Emre
Ozcom Bilgisayar Ltd.
Istanbul, Turkey
General information
Forum:
Visual FoxPro
Category:
Coding, syntax & commands
Miscellaneous
Thread ID:
01277433
Message ID:
01278086
Views:
43
I can use type for if there is a field in table:

?type("mytable.myfield")="U"

but with vartype

?vartype("mytable.myfield")="U"

is generates variable not found. Isn't that a bug?


Using TYPE() and VARTYPE()

TYPE() is an old Foxpro function which was originally introduced into the language to help when writing ‘black-box’ code by providing a mechanism to check what data type a variable or expression was using. VARTYPE() was introduced in VFP 6.0 and is much faster than TYPE(). VARTYPE() also has additional capabilities to handle testing objects. But they both have their own little peculiarities that complicate their use. To illustrate, consider the following table

Test Item TYPE() Returns VARTYPE() Returns
1 “Something” U C
2 lcVar (= “Something”) U C
3 “lcVar” C C
4 DATE() ERROR “Function argument value, type, or count is invalid” D
5 “DATE()” D C

Let’s examine TYPE() first

The way TYPE() works is confusing at first glance (and at later glances, too, actually). Remember the original purpose was to help you build black-box code. When you're working in that situation, you usually get a reference to something that has a value (typically as a parameter) rather than the value itself. TYPE() is set up on the assumption that you are in that situation and, therefore, provides for two levels of indirection. First TYPE() evaluates the string you pass it. Second, it evaluates (well, more accurately, pseudo-evaluates) the result of the first evaluation and gives you back the data type of the result of the second evaluation.

So, in the examples shown, TYPE() returns an undefined result at line 1 and 2 because the value it is testing in either case is a literal value and does not refer to anything else - there is no variable defined as ‘Something’. However, by enclosing the reference to lcVar in quotes (line 3) we give TYPE() something for the first level of evaluation to work on, VFP knows that lcVar is a variable which points to the character string “Something”. So the second level kicks in and correctly tells us that “lcVar” is of type “C” - Character.

Similarly, testing the DATE() function with TYPE() causes an error because Visual FoxPro cannot evaluate a Date (which is what this function returns as a first level evaluation) in any meaningful way. Again, enclosing the function call in quotes enables the two levels of evaluation to work properly and we get the expected result.

(By the way, EVAL() uses the same technique on its parameter. The difference is that it actually returns the result of the evaluation of the contained expression rather than its type.)

So much for TYPE(), now what is going on with VARTYPE()?

As you have probably guessed already VARTYPE() uses only a single level of indirection (which is why it is faster). What VARTYPE() does is to evaluate whatever you pass to it and return the result it gets. This is why, in the table of examples, VARTYPE() returns “C” - a character string for all of the first three values it receives. Since it never goes beyond the first evaluation all three of these will result in a “C” data type - which, in this case happens to be correct. However it is only correct in Line 3 because the variable happens to be pointing to a character string - if the value in “lcVar” was anything else it would not change the result - VARTYPE() would still return a data type of “C”.

This is shown clearly by the results of testing the DATE() function at lines 4 and 5. In Line 4 VARTYPE() correctly gets the data type “D” - because it evaluates DATE() and returns the type of the result. Conversely when passed “DATE()” at line 5, it comes back with a character data type.

When should you use which?

There are two specific situations in which VARTYPE() should be used in preference to TYPE(). First, when testing parameters passed to a method or procedure. You must, in Visual FoxPro always define the receiving variable when passing a parameter so there is never any doubt that the variable will exist and one level of evaluation is all that is needed. A side benefit here is that you do not need the quotation marks around the parameter name. Thus:
LPARAMETERS tcName
IF ! (VARTYPE( tcName ) = “C”)
	RETURN
ENDIF
Will give the correct result and execute much faster than the exactly equivalent:
IF ! (TYPE( “tcName” ) = “C”)
The second use for VARTYPE() is when checking for the existence of an object. If an object exists, VARTYPE() returns a data type of “O”. If the object reference exists, but there is no longer an actual object (i.e. the reference is NULL), then VARTYPE() returns a value of “X”. Thus:
oForm = CREATEOBJECT( “FORM” )
? Vartype( oForm )	&& Returns “O”
oForm.Release()	&& oForm = NULL
? Vartype( oForm )	&& Returns “X”
TYPE() does not support the “X” data types, and the only equivalent is the cumbersome and (very) slow:
IF TYPE( ‘oForm’ ) = “O” AND ! ISNULL( oForm )
In addition to these two specific occasions, VARTYPE() can also be used anywhere that you are sure that only one level of indirection will be required. So what does that leave for the poor old TYPE() command?

Well, TYPE() works in some cases where VARTYPE() doesn't. For example, although VARTYPE() does return "U" if you pass it a variable that doesn't exist (as in VARTYPE(NonExistent) ), it doesn't have the ability to drill down through containership hierarchies to determine whether a property exists. So, while you can successfully use code like:
IF TYPE("oForm.Name") = "U"
the corresponding use of VarType:
IF VarType(oForm.Name) = "U"
gives an error message if oForm doesn't exist or is null. (The exact message depends on the circumstances). This is because VARTYPE() can only deal with non-existent properties at the last level of the containership. So, if oForm exists, but you ask about a property that doesn't, e.g. VARTYPE(oForm.Fred), you get a result of "U"; but if oForm does not exist you get an error.

On the other hand, TYPE(), because of its two-pass evaluation, does not generate an error, you merely get a result of “U”. Of course still this does not tell you which of the two possibilities has actually occurred (either the form exists and the property doesn’t OR the form does not exist!) but it won’t break your code either - be thankful for small mercies.
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform