Dot Variables in Alpha Five

By Dr. Peter Wayne

Dot variables are a special type of variable in Alpha Five. They will become more useful in A5v5, so you might as well learn about them now!
Warning - I would consider this article to be on an "advanced" level. If you're an Xbasic beginner, just skip this one now and come back to it in a few months.

A simple variable in Xbasic is a address, or a series of addresses, in your computer's memory in which a value is stored. The simple variable types that Alpha Five supports include:

The pointer variable type is a special variable. If you could peek inside your computer's RAM and look at the memory address where A5 has stored, say, a pointer to an open table, you would not find the actual table information A5 needs to manipulate the table, but instead you would find another address at which the table info is kept. Let me give an example. Suppose you write

dim tbl as p
tbl=table.open("customer")

If I found that tbl were stored at memory locations 100000-100004 in my computer, then if I were to look at what is stored in memory location 100000-100004, I would find another address, perhaps location 20004068. If I could then peer at location 20004068 I would find a whole sequence of memory locations that store information about the table's access mode, my position in the table, the record buffer for the table, etc. So a pointer is aptly named in that it points to the location where the actual working data is kept.

In contrast, if I write

dim mynum as n
mynum=12.5

If mynum were stored at memory locations 100005-100008, then a look at those locations would show that "12.5" is stored there directly. The memory locations for numeric, logical or date variables store the actual values of those variables. The memory locations for pointer, character, and blob variables just store more addresses where the variables can be found (I assume that character and blob variables are implemented as pointers.)

Compound or Dot Variables

There's another kind of variable in Alpha Five, the compound or dot variable. You've used those variables without being aware of it. For example, look at this code fragment:

dim query.filter as c
dim query.order as c
query.filter="state='MA'"
query.order="company"
customer.query_create()

Here there are 2 dot variables, query.filter and query.order . What is not obvious is that there is an undeclared variable, query , which is a pointer variable. You can create your own "dot" variables by declaring pointers and then declaring sub-variables after the "dot." For example:

dim ptr as p
dim ptr.name as c
dim ptr.rank as c
dim ptr.num as n
ptr.name="peter"
ptr.rank="corporal"
ptr.num=131
ui_msg_box("My name, rank and serial number",\
ptr.name+chr(13)+chr(10)+ptr.rank+chr(13)+chr(10)+\
alltrim(str(ptr.num)))

Script 1. My first compound variable.

Running this script produces this output:

Figure 1

Figure 1. Output of Script 1.

Functions and dot variables

So far we haven't done anything particularly exciting with dot variables, but bear with me - we're still laying the groundwork. Consider a normal Alpha Five function: it takes one or several parameters and returns a single value. Alpha Five functions cannot change the value of a simple variable. For example, look at this script:

dim ptr as p
dim ptr.name as c
dim ptr.num as n
ptr.name="peter"
ptr.num=1
' parameter=based function
function change_name as l(name as c, num as n)
	name="finian"
	num=2
	change_name=.t. 
end function
change_name(ptr.name,ptr.num)
ui_msg_box("after change_name","name is still "+ptr.name)
end

Script 2. Typical function call in Alpha Five.

The output of this script is:

Figure 2

Figure 2. A typical function does not change the value of its parameters.

What if we want to change the actual value of ptr.name? Can we do it in a function call? The answer is "yes," but instead of passing the function the dot variables, we need to pass the function the pointer itself:

dim ptr as p
dim ptr.name as c
dim ptr.num as n
ptr.name="peter"
ptr.num=1
' pointer-based function
function change_ref as l(p1 as p)
	p1.name="Captain Marvel"
	p1.num=3
	change_ref=.t. 
end function
change_ref(ptr)
ui_msg_box("after change_ref","name is "+ptr.name)
end

Script 3. A pointer-based function.

The output of this function is now:

Figure 3

Figure 3. A pointer-based function lets me change my name.

What we have done with pointer-based function is to change the actual value of ptr.name in the main script. In computer-ese this pointer-based function does a pass by reference and Alpha Five's usual function call is a pass by value.

One use of the pass by reference capability of function calls is to break up large scripts into smaller modules. Instead of declaring shared variables in each module, we can pass a single pointer to a series of global functions, each one of which can extract and work on the dot variable component it needs.

Multidimensional arrays

We can also use dot variables to create multidimensional arrays. Alpha Five only allows single-dimensional arrays, e.g.,

dim my_array[3] as c
my_array[1]="peter"
my_array[2]="finian"
my_array[3]="barry"

With the use of pointers, however, I can create 2-dimensional arrays:

' 2-dimensional arrays
dim super_heroes[3] as p
for i=1 to 3
	dim super_heroes[i].names[2] as c
next
super_heroes[1].names[1]="peter"
super_heroes[1].names[2]="Captain Marvel"
super_heroes[2].names[1]="finian"
super_heroes[2].names[2]="The Flash"
super_heroes[3].names[1]="barry"
super_heroes[3].names[2]="Batman"
dim heroes[3] as c
for i=1 to 3
	heroes[i]=alltrim(str(i))+" "+super_heroes[i].names[2] 
next
choice=ui_get_list_array("Choose a hero",1,"heroes")
chosen=val(choice)
ui_msg_box("The secret identity of "+super_heroes[chosen].names[2]+" is",\
super_heroes[chosen].names[1])

Script 4. 2-dimensional arrays in Alpha Five.

Running this script produces this output:

Figure 4

Figure 4. Choosing "Batman".

And then we see that Batman is really:

Figure 5

Figure 5. Members of the NY Alpha Users Group knew this all along.

Setting one pointer to another

What happens if you set one pointer equal to another? Let's say we write

dim customer as p
dim t as p
t=table.open("customer")
t.fetch_first()
customer=t
? customer.firstname
= "Michael             "

Assigning one pointer to another makes the "dot variables" of the first pointer accessible to the second. Here is another example:

t=table.open("c:\program files\a5v4\samples\invoice\customer.dbf")
t.fetch_next()
customer.name=t.firstname
cust1=customer
? cust1.name
= "Sally               "

In this example, the cust1 pointer automatically inherits the name sub-variable from the customer pointer.

Dot variables are not limited to one level. You can create a whole "tree" structure for a dot variable:

t=table.open("c:\program files\a5v4\samples\invoice\customer.dbf")
t.fetch_next() 
dim customer.name.first as c 
dim customer.name.last as c
customer.name.first=t.firstname 
customer.name.last=t.lastname 
? customer.name.last
="Peabody " 

Dot variables in version 5

Alpha Five version 5 will allow the Xbasic programmer to establish permanent global variables through the use of dot variables. There are methods in v5 to enable you to

Of course, if you write dot variables to your Windows registry, you should realize that they will not be available to other computers on your network. That could be an advantage - you could, for example, place user-specific Alpha Five preferences in each user's Windows registry. Or you could place database-specific preferences in the database file, remembering that these preferences will not be shared across a network that is network optimized. If you want to share data among users, you still should put the data in tables.

11/25/99

Don't forget, we need your feedback to make this site better!

Return to home