Welcome!

PowerBuilder Authors: Dan Joe Barry, Carmen Gonzalez, Ian Thain, Yakov Werde, Paul Slater

Related Topics: PowerBuilder

PowerBuilder: Article

Getting Rid of Global Variables

We can live without them

It may seem as if PowerBuilder programmers are bound to use global variables. Even the PFC, which is said to be the most successfully designed object-oriented framework, requires the use of global variables. Is it something in the nature of PowerBuilder that makes us use them? I won't discuss whether it's good or bad to use global variables as enough has been said on this subject. However, I am going to discuss why global variables are usually used in PowerBuilder applications and how we can live without them.

When Global Variables Are Used
Let's face it, if you use global variables, it means you need them. I have come across two cases in which global variables are used in PowerBuilder applications. The first case is the need to have a named literal value referenced by many objects of an application that is referenced globally. As will be shown later in this article, the usual final point of satisfying this need is a declaration and the use of global constants.

The second case is the need to have what is nowadays called a "service," that is an object that provides some service for other objects. The provided service may be that the object knows and provides some information, performs some work, offers some computing service, etc. If such an object needs to keep some information between calls for its service (keep their state), it needs to exist during the time when the program is running. Naturally, such service objects need to be referenced globally too. Again, as will be shown below, a usual final point of satisfying this need is a declaration and use of global variables of the type of the service objects.

As a result, in both cases we have a declared global variable referenced in many places in an application. That is, we have a dependency on a global variable in the application. Sometimes we can live with it, but what if a declaration of another global variable for an application is highly undesirable or if a global variable can't even be declared? Suppose you're developing a module that will be plugged into an application dynamically. In this case, you can't declare a global variable that is referred to by different objects of your module. A dead end? No. Actually, a declaration of global variables is not at all necessary. The thing is, PowerBuilder does it for you.

What Can Be Done
As you may already know, when you create a userobject in PowerBuilder, you not only create a class, but PowerBuilder also declares a global variable of that class with the same name. You can see this if you look at the source code of any object; after a declaration of the type, for example:

global type n_cst_appmanager from pfc_n_cst_appmanager
end type

there is a declaration of the global variable:

global n_cst_appmanager n_cst_appmanager

(Note: It happens unless you make an autoinstantiated object. In this case, PowerBuilder does not declare a global variable of that type.)

If we could use this implicitly declared global variable, we wouldn't need to declare our own. Another interesting and useful effect of this use would be that since the global variable has the same name as its class, we would be able to reduce the dependency on a global variable to the dependency on a class, at least in terms of names. The question is whether we can use such global variables. Luckily, the answer is yes, we can. Moreover, as will be shown later, in some cases we can reduce the dependency on a global variable to the dependency on a class, not only in terms of names.

Constants: The Problem
You know the story. First, you need a literal value in one place in your script, so you just type it in (unless you're a very disciplined programmer and don't allow "magic numbers" to appear in your source code). Then, you discover that you need it in another place. You may type it in again, but you start thinking about the maintenance of the source code. If the value is numeric and represents some code, you may decide to use string values instead. For example, in earlier versions of the PFC you could come across code values like "FixedToRight" or "FixedToBottom" in the Resize service object. It's much better in terms of readability of the source code, but not so good from a maintenance and error-detection perspective. If for some reason you need to change the code value, you'll have to change it everywhere you used it. As for error detection, it's much better when you discover a mistype in a code value when you compile your script than when you run your program (or even worse, when your user runs it). With the preliminary step of the use of string values or without it, you come to a decision to use constants.

Constants: The Solution with Global Variables
Usually, when you need a named literal value that will be referenced in different parts of your application, you declare a global constant, for example:

Constant String sINIFILE = "example.ini"
Constant String sVERSION = "6.0"

In real-world applications, however, you may end up with dozens of global constants. To cope with this, you can place logically connected constants in several user objects. For example, you can find the Color object in the PFC that contains a set of constants you can refer to for specifying color values. Then, you can declare global variables of those classes instead of individual constants, reducing the number of global variables.

Constants: The Solution Without Global Variables
As an alternative to a global declaration of the user object that contains a set of constants, you may make it an autoinstantiated object and declare a variable of this class wherever you need its constants. For example, the previously mentioned Color object from the PFC is made so, and you use it right after the declaration of a variable:

n_cst_color lnv_color

rte_1.SetTextColor(lnv_color.CYAN)

But actually even such a declaration is redundant. Do you remember that PowerBuilder implicitly declares a global variable with the same name for each user object that is not autoinstantiated? The thing is, you can refer to constants, declared as instance variables of a user object, without the creation of the user object. As far as I know, it's not documented but it's a well-known fact in the PowerBuilder community. If the PFC Color object weren't defined with the autoinstantiate option, you would be able to use its constants referring to the object name, as in the previous example:

rte_1.SetTextColor(n_cst_color.CYAN)

Now you know what to do. For each group of constants that you need (or for all constants - it's up to your design decision), create a user object and declare your constants as instance constants of the object. Then, whenever you need the constant, simply use the "object name-dot-constant name" notation.

Services: The Problem
By services I mean the objects that provide some service to other objects or, to put it more generally, to the whole application. There can be several kinds of such objects in your application:

  • Information holders: Objects that know and provide information
  • Service providers: Objects that perform work and offer computing services
  • Structures: Objects that maintain relationships between objects and information about those relationships
(Note: If you are interested in more details, refer to the book Object Design: Roles, Responsibilities, and Collaborations by Rebecca Wirfs-Brock and Alan McKean.)

In most cases, it's enough to have the scope of such service objects as instance (or shared) variables or even local variables. In this case, all the data that's needed for the object to perform its task is specific to the current invocation of the object's service. But sometimes the lifespan of the object should be the same or almost the same as the lifespan of your application. In addition, it may be desirable that only one instance of the object existed and all client objects call for the same instance. Remember the PFC Application Manager object and you'll get an example of such an object.


More Stories By Konstantin Goldobin

Konstantin Goldobin is a senior developer living in Voronezh, Russia. He has been working with PowerBuilder since 1995 version 4.0. Visit his web site at www.vsi.ru/~kgold.

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.