Variants


A Variant is a special kind of data type. In fact, it's really a class, in contrast to a data type, but in the effort to make things easier for you, you use a Variant just like you use a data type when it comes to declaring it.

What's special about a Variant is that it is a data type that can hold any kind of data. It doesn't care if it's a string, an integer, or even an object. After you have declared the Variant, it can accept any data type.

Dim v as Variant Dim i as Integer Dim s as String i = 1 s = "One" v = i MsgBox v.StringValue v = s MsgBox v.StringValue 


As you can see in this example, the same Variant accepted assignment of data that was an integer and a string. It also provides a method StringValue that returns the value of the Variant expressed as a string (which is one of those things that makes it really more of a class than a data type).

A Variant has the following properties that are used to access the data the Variant represents as different types. Remember that because a Variant can be any type, you'll need to do some things when working with them.

Variants and Operators

Variants can be used in place of data types in many cases. If a method calls for an integer as a parameter, you can pass a Variant instead. Variants also work with operators, but you have to be careful. Because operators can be overloaded, you need to make certain that the operator will work the way you think it will.

Dim v as Variant Dim w as Variant Dim i as Integer Dim j as Integer v = 2 w = "3" i = v * w // i = 6 j = v + w // j = 23 


In this example, I started with two Variants, v and w. v was assigned the value of an integer and w was assigned the value of a string. When I multiplied v times w, I got the value of 6, which is what I would expect when multiplying the two times three. When I add the Variants v and w, I do not get the answer five. Instead, I get the value 23.

The reason for this is that the + operator is overloaded for strings. When REALbasic encounters that operator with two Variants, it has to choose whether to use the + operator for adding two integers or the + operator for concatenating two strings. Because * is not overloaded for strings and there is no ambiguity, REALbasic uses the integer value for both Variants. In the case of the + operator, REALbasic defaults to treating them like strings and concatenates 2 and "3" to make 23. It then coerces the string 23 into an integer.

Properties

Variants all have the following properties, which allow you to access the value of the Variant in whichever data type you choose:

aVariant.BooleanValue As Boolean aVariant.ColorValue As Color aVariant.DateValue As Date aVariant.DoubleValue As Double aVariant.IntegerValue As Integer aVariant.ObjectValue As Object aVariant.StringValue As String 


Not every variant value can be expressed in all the options you have for expressing them. For example, if you create this Variant:

Dim v as Variant Dim o as Object v = 1 o = v.ObjectValue 


There really is no ObjectValue for v, because the Variant v represents an integer and an integer is one of REALbasic's intrinsic data types. If you test to see if the object is Nil, you'll see that it is not Nil, but you can't do anything with it. Before accessing a property such as ObjectValue, you would probably want to check to see what type the underlying object or data type is prior to accessing one of these properties directly. You can do this with the VarType global function, or the Variant function Type.

DateValue returns a Date object. See the discussion of the Date class to see how the different values of a Variant are returned when the underlying object is a Date. The reason a Variant returns a Date is for the sake of compatibility with Visual Basic, which has a Date intrinsic data type.

Methods

The following methods are available to Variants as well.

aVariant.Equals(aVariant as Variant) as Boolean 


This method tests to see if one Variant is equal to another. "Equality" is a little different when talking about Variants. Consider the following example.

Dim v as Variant Dim w as Variant Dim b as Boolean v = 2 w = "2" b = v.Equals(w) // b equals True 


Even though v and w started off as different types (an integer and a string), they are still viewed as equal by a Variant because their IntegerValue and StringValue are the same.

aVariant.Hash() as Integer 


According to the documentation, Hash returns an integer that is guaranteed to be unique for integers and colors. It is also guaranteed to be unique for objects that are in existence. From my experience, it also generates unique values for strings and floating-point values.

Dim v as Variant Dim w as Variant Dim x,y as Integer Dim b as Boolean v = 2 w = "2" x = v.hash() // x = 13074 y= w.hash() // y = 50 b = (x=y) // b is false 


As you can see from this example, if we use the same Variants from the previous example that evaluate to true when using the Equals function, we get different values for their hashes. You can use the hash value to assess equality in a slightly different way than you can with the Equals function. In this case, because v starts off as an integer and w starts off as a string, a different hash value is generated. When you test for the equality of the hash, you will find that they are not equal.

aVariant.isNull() as Boolean 


If a Variant has been declared, but has had no value assigned to it, the isNull function will return true. Otherwise, it's False.

aVariant.IsNumeric() as Boolean 


This tests to see whether the value stored by the Variant can be expressed as a number, regardless of whether it was originally a string.

Dim v as Variant Dim w as Variant Dim b,c as Boolean v = 2 w = "2" b = v.isNumeric() // b is True c = w.isNumeric() // c is True 


In both cases, v and w, isNumeric returns true.

aVariant.Type() as Integer 


Returns the integer value that represents the Variant type. See the section "VarType" for details about what the integers mean. This function is sensitive to the type of the original value the Variant was set to.

Dim v as Variant Dim w as Variant Dim x,y as Integer v = 2 w = "2" x = v.type() // x is 2, which means Integer y = w.typoe() // y is 8, meaning String 


VarType

There is a global function, VarType, that you can use to determine what kind of data is contained in a Variant. You pass a Variant as parameter to the VarType function, and it returns an integer that will tell you what type the data is, as follows:

0

Nil

2

Integer

5

Double or Single

7

Date (An object, not a Data type, but is included for Visual Basic compatibility. Recall that VB treats dates as data types.)

8

String

9

Object (In very early versions of REALbasic, 13 was returned for an Object.)

11

Boolean

16

Color


Consider the following example:

Dim result as Integer Dim v as Variant Dim i as Integer i = 1 v = i result = VarType(v) 


In this case, result equals 2.

Dim result as Integer Dim v as Variant Dim s as String s = "One" v = s result = VarType(v) 


And in this case, result equals 8.

When to Use Variants

When I first started writing this section, I had to dig around a lot of old code of mine to see if I had ever used one. I had, in fact, used them on a few, limited occasions.

The problem, as I understood it then, is twofold. First, because Variants can hold data of any type and return it as any type, there's a lot of overhead required to manage this process. This makes Variants slower than using the actual type. The second problem is that if your program is well designed, you should always know what kind of data to expect. If you are effectively using the object-oriented features of REALbasic, you really won't ever need them because classes, subclasses, and interfaces provide you with some of the same flexibility as a Variant, but in a way that is more manageable over time.

Does that mean you should never use Variants? No, not at all. There are many situations where you will need to get a string representation of an integer, for example. The most common reason is that you have an integer and you want to display it in your program, and this requires that you convert it to a string first to display it.

There are a couple of ways to do this. The first is with the Str function, which we discussed in the "String" section. Variants offer a second way of doing it.

Dim v as Variant v = 100 EditField1.text = v.StringValue 


Here you can see that by using a Variant instead of an integer, it's a fairly straightforward process to accomplish that. Here's how the same thing looks using the Str Function:

Dim i as Integer i = 100 EditField1.text = Str(i) 


Because I wasn't really a big fan of Variants, I decided to do some tests using integers to see just how much slower the code that used Variants was, and this is what I found:

  • Assigning an integer value to a variable declared as a Variant is, indeed, much slower than assigning an integer value to a variable declared as an integer.

  • Converting an integer to a string is much slower using Str() than it is using Variant's StringValue().

  • Str() is so much slower than StringValue() that if you have an integer that needs to be viewed as a string (usually this is to show it in an EditField on screen), it makes sense to use a Variant because when you look at it from the perspective of both assignment and conversion, Variants are faster. In other words, this:

    Dim v as Variant Dim s as String v = 100 s = v.StringValue() 

    is faster than this:

    Dim i as Integer Dim s as String i = 100 s = Str(i) 

When coercing a single integer, the speed difference isn't enough to notice, but nevertheless, a Variant is faster. Go figure.




REALbasic Cross-Platform Application Development
REALbasic Cross-Platform Application Development
ISBN: 0672328135
EAN: 2147483647
Year: 2004
Pages: 149

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net