A Better Way to Initialize Global Variables

by Dr. Peter Wayne

This article grew out of a discussion at the July 2002 New York Alpha Five Users' Group meeting. It started with a comment made by Mike Pesach about an application presented by Daniel Weiss, and developed into the short scripts presented here.

Frequently the application designer (that’s you!) will need to initialize a series of global variables when the application starts. Typically these variables will include the site’s name, perhaps the license number of the application, the site’s address, and other site-specific data that will appear on reports and forms throughout the application.

The usual way these variables are stored is to place them in a single table, sometimes called “site.dbf” or “main.dbf”, with one field for each variable. As the application designer, you enter the site-specific values into each field. For example, here is the structure of a hypothetical “app_site.dbf”:

Field Type Width
Site_Name C 100
Registered L
License_Num N 6,0
Version N 6,2
Telephone C 14
better1
And we would typically fill in the fields from the default form or browse: better2

Our autoexec script would read the site-specific parameters into global variables, as in

dim global site_name as c
dim global license_num as n
dim global registered as l
dim global version as n
dim global telephone as c
dim t as p
t=table.open("app_site",file_ro_shared)
site_name=t.site_name
license_num=t.license_num
registered=t.registered
version=t.version
telephone=t.telephone
t.close()

Script 1. Typical application's autoexec script.

What happens if, as our application evolves, we need to add another global variable to the application? We have to change the structure of site.dbf, make the field entry in the default form, and then change the autoexec script to create the new global variable and read it from the app_site table. Although this is not very difficult with one site, if you are fortunate enough to have your application at multiple sites, then as you keep making changes at one site or another you are faced with the daunting task of either updating all your sites, or keeping track of which site has which version of app_site.dbf. Is there a more generalizable way to add new site-specific data to each database?

You betcha there is! In Application Programming for Alpha Five, published by Alpha Software, I show how you can write data directly to the application’s .adb file. That method works only for Alpha Five version 5. Here I will develop a different technique, one that is equally applicable to versions 5 and 4.5.

We start by creating a new table, app_settings.dbf, with 3 fields, my_var, my_type, and my_value:
better3

Each field is of type Character.

I then fill the table with the variables, their types, and values specific to the site. Each variable occupies one record in this table:
better4

Notice that the values for the character variables are surrounded by quotation marks, and the logical field contains .T. or .F., that is, the same syntax used in Alpha Five expressions must be used in this table.

We then create a script that will read each record in the table, create global variables, and then initialize them. In v5, the process of creating global variables is made simple by a function, evaluate_template(cmd_string), which executes the code found in cmd_string. It is similar to eval() but can execute commands that cause eval() to choke. For example, we can use evalute_template() to execute

evaluate_template(“dim global site_name as C”)

This command cannot be executed by the eval() function.

So, in v5, we can write this autoexec script:

t=table.open("app_settings",file_ro_shared)
t.fetch_first()
while .not. t.fetch_eof()
	evaluate_template("dim global "+trim(t.My_var)+" as "+trim(t.my_type))
	evaluate_template(trim(t.my_var)+ "=" + trim(t.my_value))
	t.fetch_next()
end while
t.close()
end

Script 2. Autoexec script for A5v5.

This simple script loops one at a time through each record in the app_settings table, reads each record, creates the global variables and initializes them to the appropriate values. After the script has run, we can inspect the list of global variables (in v5, there is a special dialog box that shows global variables):
better5

But what if you are still working in v4? There is an old function, submit(), around since Alpha Five version 1, that accomplishes pretty much the same thing that evaluate_template() does, except that submit() requires the “session handle” of the A5 session in which the cmd_string will be executed. Fortunately, there is a companion function, session_get(), that returns the session handle. So in v4.5 we can write

t=table.open("app_settings",file_ro_shared)
t.fetch_first()
while .not. t.fetch_eof() 
	submit(session_get(),"dim global "+trim(t.my_var)+" as "+trim(t.my_type))
	eval(trim(t.my_var))=eval(trim(t.my_value))
t.fetch_next()
end while
t.close()
end

Script 3. Improved Autoexec script for A5v4.5

In v4.5, you can inspect the global variables through the Xbasic Explorer:
better6

We can see that these global variables were properly initialized.

Let’s put it all together with a script that will work in either v4.5 or v5. We will call on the built-in A5v5 function version(), which returns the version number of Alpha Five. In v4.5 this function is undefined. We will place an error trap in our code so that if we are not in v5 we will execute v4.5-specific code, but if we are in v5 we will execute v5 code:

t=table.open("app_settings",file_ro_shared)
t.fetch_first()
on error goto not_5
if version()>=5 then
	on error goto 0
	while .not. t.fetch_eof()
		evaluate_template("dim global "+trim(t.My_var)+" as "+trim(t.my_type))
		evaluate_template(trim(t.my_var)+ "=" + trim(t.my_value))
		t.fetch_next()
	end while
end if
t.close()
end

not_5:
while .not. t.fetch_eof() 
	submit(session_get(),"dim global "+trim(t.my_var)+" as "+trim(t.my_type))
	eval(trim(t.my_var))=eval(trim(t.my_value))
	t.fetch_next()
end while
t.close()
end

Script 4. Improved Autoexec script that can be used in either v4.5 or v5.

7/14/02

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

Return to home