Tips_todo   >   Objectclasses   >   Custom Constants Using Object Classes

Custom Constants Using Object Classes

There are many differing opinions on the best place to store your own global variables. I expect a search for "global variables" or "constants" at OmniGuru will give you lots of different ideas.

I've tried a few different things. I don't have the perfect solution, but I'm pretty happy with it.

I regard constants as 'Memory-Only' type data which gets set up on opening the library, or at the moment a method requests the value of the constant. Therefore, I don't want to store my constants in the 'data file'.

When I first started using Studio, I put my 'constants' in the Startup_Task task variables. This worked until my task variables pane started to get cluttered with all kinds of constants, many of which I only needed occassionally.

I tried using an Omnis Memory-Only file format. This works pretty nice with the F9 catalog. You can view and drag and drop the constants directly into your code. However, I use multiple libraries for my application and any constants in my sub-libraries would get scary to read when I closed the other library which had the memory-only file formats. (They change to the file format mapping number right before your eyes. Makes the code a bit hard to read.)

I tried moving my constants from the Startup_Task task variables to the Startup_Task instance variables. This worked good for decluttering my task variables pane, but I could no longer 'view' the constant names from anywhere in my application, so a spelling error meant the code would not work, and if I forgot the exact spelling, I'd have to go to the Startup_Task, look inside, click the instance variables pane, then go back to my code.

STORING CONSTANTS IN AN OBJECT CLASS's CLASS VARIABLES

I have now settled on storing my constants in the class variables of an object class (Can you tell I like object classes?). I create an object class called "oConstants" which has class variables for each constant I want to store and a matching public method for that constant which returns the constant value.

Using class variables allows me to set up the object method so that if the value is blank, code is executed to calculate the constant value and then return the value, otherwise the value is simply returned. For known constant values I might use the "Init. Val/Calc" column in the variable pane for the class variable value.

I then instantiate the object class "oConstants" as a task variable named "cn" in my Startup_Task. Any method within the scope of the Startup_Task can use the Interface Manager to drag and drop the appropriate constant method into its code. In fact you can use them as "in-line" calculations.

e.g. Calculate WavFilePath as con(cn.$retPathCurrentDir,'sounds',sys(9),'click.wav')

If you have muliple libraries running under different tasks, and need to access the constants in another library, you simply need to make the "oConstants" property $external=kTrue, and make a unique task variable "constantsLIBNAME" variable and then point it to the "oConstants"" of the other LIBNAME.

Note: You don't have set up "oConstants" as a task variable, you can just call it on the fly. Since they use class variables to store the contants, the values are not lost when the object instance closes.

LOOKUP LISTS

I have also started using the above concept for Lookup lists, with an object called "oLookups". If the list is empty when oLookup.$LISTNAME is called, the object class builds the list from the data file, then returns the list to the calling method. Otherwise, if the list has already been built,the list is simply returned. I use an optional parameter pRebuildYN_opt which if set to kTrue, will force the method to rebuild the lookup list.

Hope this helps you with deciding which option works best for storing constants in your application.

Getting Constants

Two of the approaches you can use for getting Constants are:
1. Use a method called $getCONSTANTNAME(pfGetValue)
2. Use a method called $retCONSTANTNAME() Return Value

I prefer the 2nd method because it means less methods in my object class. The 2 methods are shown below.

$getValue(pfGetUserName)
Calculate pfGetValue as cValue
Quit method kTrue

$retValue
Quit method cValue

With the $retValue format, you can use the method in an inline function.
e.g. Calculate Name as con("The Honourable ",cn.$retUserName())

Row Variable Constants

One of the problems I ran into with row variable constants was to be able to user the '$retRow' in an in-line function. I couldn't figure out how to put the constant row directly in-line with the column name.

Thanks to Reg Paling & Weitse Jacobs for the solution. The trick was to return a reference to the row variable.

$retRow(pSetValue_opt) Returns RowReference
If not(isnull(pSetValue_opt))
Calculate cRow as pSetValue_opt
End If
Quit method cRow.$ref ;; Whether a get or set, this method returns the Row

Note: Using $ref as the return value would not work if cRow was replaced with a local variable. The reason is that when the $retRow method has finished the local variable values are destroyed. The calling method will be left referencing a variable that is no longer alive. This happened to me because I had a situation where I was first calculating the constant value to a local variable, then updating the class variable, but made the mistake of returning the row variable reference using the local variable instead of the class variable.

Setting Constants

Two of the approaches you can use for setting Constants are:
1. Add a method called $setCONSTANTNAME
2. Include an optional parameter in your $retCONSTANTNAME method

I prefer the 2nd method because it means less methods in my object class. The 2 methods are shown below.

$setValue(pValue)
Calculate cValue as pValue

$retValue(pSetValue_opt)
If not(isnull(pSetValue_opt))
Calculate cValue as pSetValue_opt
End If
Quit method cValue ;; Whether a get or set, this method returns the current UserName