You might think that global shared objects are a better way to go in new applications than non global shared objects, because multiple procedures that are not necessarily running in a single predictable procedure call stack can all access them. Also, any of the procedures can define them first and others can define them and use them in any order. Thus, you could place a set of global definitions into an include file and include it in every procedure that needs them, without regard for which procedure has to use the NEW keyword in its definitions.

Up to a point this is correct, but there are good reasons why you should generally avoid global shared objects in new applications:
  1. Simply having an include file that many procedures depend on is poor practice in a modern application. Any time the list of definitions in this file changes for any reason, every procedure that uses it must be recompiled and potentially redeployed. As you learn more about dynamic language constructs in later chapters, you learn useful alternatives to global shared variables that are more flexible and can change at run time without any code changes or recompilation at all.
  2. Global shared objects create potential namespace conflicts and possible unintended consequences in your application, precisely because they are global. A global shared object is visible to every procedure in the entire session, and every procedure shares that name and its value. Global shared objects never go out of scope and they cannot be deleted. They exist from the time the first definition is encountered until the session ends. An important aspect of a modern application is that it is as modular as possible, with code and data for a particular module isolated within a set of procedures that can run independently of other modules. What happens when two modules happen to use the same name for a global object? The result is that ABL defines just one object, with a single value, and two different sets of code are trying to use it for different purposes. Very insidious errors can result.
Thus, it is generally advisable that you should avoid global objects wherever possible. If you do think you want to use them, consider these important guidelines:
  • A global shared variable or other object can be somewhat faster to access than an alternative that involves using possibly dynamic language statements to refer to a value defined elsewhere. All the procedures that use the global shared object are pointing directly to its memory just as if it was defined locally. Therefore, you can consider using global shared variables or other objects for a small number of values that are critical to your application, used with great frequency, and truly global in their use.
  • Because global shared objects exist in a single namespace across the entire session, and because they cannot be deleted, you should be very careful in naming them. Use a naming convention that prevents any chance of two different procedures using the same name for different purposes. Perhaps the easiest way to do this is to have a single include file for your entire application that holds all its global definitions. Any procedure that needs any of them includes this same file, so that (as long as they are recompiled together) they remain in sync and there is not a chance of another developer inadvertently giving another global object the same name.