Tips   >   Objectclasses   >   Custom Constants

Custom Constants

There are many differing opinions on the best place to store your own global variables. I have 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 Omnis 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 a File Class as a memory only file mode. Using a file class 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 format. They change to the file format mapping number right before your eyes making 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 variable names from other classes in my application. 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. Not very convenient.

The solution I finally settled on was to create an oConstants object class which gets instantiated by the Startup_Task task variable cn.

I then add a property method for each constant value which I need for my application.

Each of these property methods returns the specified constants value.

If I want to be able to set any of the properties I add a $:AppName.$assign(pValue) setter method.

I then add an object type task variable, cn, to the Startup_Task and point it to oConstants.

Now in the method editor from any one of my classes I can easily access any of my custom constants. The Omnis Studio notation helper assists me as I type the code.

Calculate AppName as cn.$:AppName

or

Calculate Mssg as con("Please contact the developer, ",cn.$:DeveloperName,".")

Click the View oConstants button in the StudioTips Browser window to view a sample oConstants object class.

Constants Object Class

Setting up an oConstants object class for your application's custom constants if easy to do.

  1. Create and object class and name it oConstants
  2. Add a property method for each custom constant you wish to make available to your application. For example:
    • $:AppName returns the name of the application.
    • $:DeveloperName returns the name of the developer.
    • $:CompanyName returns the name of the main company.
    • $:CompanyLogo returns the company logo.


    Each of these property methods returns the value you specify.

    ; $:AppName (method)

    ; Hard coded application name.
    Quit method 'StudioTips'

  3. If you want to be able to assign any of these value during startup, you add the appropriate .$assign suffixed method and use an instance variable for holding the value. e.g. $:AppName.$assign(pValue)

    ; $:AppName.$assign (method)

    ; Copy the value to an ivar.
    Calculate iAppName as pValue
    Quit method kTrue

    ; $:AppName (modified method)

    ; Return the ivar value.
    Quit method iAppName

  4. Add an Object type task variable, cn, to your Startup_Task, and point the variable to your oConstants object class.

Now in the method editor from any one of your classes you can easily access any of your custom constants. The Omnis Studio notation helper assists as you type the code. You can use your custom constants for in-line calculations.

Calculate Mssg as con("The application ",cn.$:AppName," has been updated.")

Click the View oConstants button in the StudioTips Browser window to view a sample oConstants object class.

Storing Constants

There are a number of techniques you can use to save and restore your custom constants. I like to use a row variable for all of the custom constants and then save the row in the database. That way, if I add a new custom constant I don't have to modify the table in the database.

Here's the steps for implementing the technique which I use:

  1. Create a schema class and name it sConstants_listdef.
  2. Leave the $servertablename property empty.
  3. Add a column to the schema class for each custom constant which you need. e.g. AppName, DeveloperName, etc.
  4. Add an $initialize method to oConstants with the following code.

    ; $initialize (method)

    ; Define the constants row variable used in this object.
    Do iRow.$definefromsqlclass('sConstants_listdef')
    If iRow.$colcount=0
       
       ; Log an error.
       ; Enter code here to suit how you are handling errors.
       Calculate FlagOK as kFalse
    Else
       
       ; Load the constants row from the database or some other source.
       ; Enter code here to load iRow from where ever the data is stored.
       Calculate FlagOK as kTrue
    End If

    Quit method FlagOK

Click the View sConstants_listdef button in the StudioTips Browser window to view a sample sConstants_listdef object class.

Auto-Add Constants Property Methods

You can automatically add property methods to your oConstants object using notation.

The technique I use is to loop through the columns of the row variable defined by sConstants_listdef in the $initialize method lof oConstants and check for the appropriate getter property methods in the oConstants object class. If a getter method is missing, I add the getter and setter methods using notation.

; $init_syncPropertyMethods (method called by $initialize)

; Preset the flag to true.
Calculate FlagOK as kTrue

Set reference rClass to $cinst().$class

; Loop through the iRow columns and check for a setter property method for each column.
Do iRow.$cols.$first Returns rCol
While rCol
   
   ; Does a getter method exist.
   Calculate MethodName as con('$:',rCol().$name)
   If not($cinst.[MethodName].$cando)
      
      ; The method does not exist. Add it.
      Do rClass.$methods.$add(MethodName) Returns rMethod
      If rMethod
         
         ; Set the method text.
         Calculate Text as con("Quit method iRow.",rCol().$name)
         Do rMethod.$methodtext.$assign(Text)
         
         ; Does a setter method exist.
         Calculate MethodName as con('$:',rCol().$name,'.$assign')
         If not($cinst.[MethodName].$cando)
            
            ; The method does not exist. Add it.
            Do rClass.$methods.$add(MethodName) Returns rMethod
            If rMethod
               
               ; Add a field reference parameter. (Last parameter 'bIsParameter')
               Do rMethod.$lvardefs.$add('pfValue',kFieldreference,,,kTrue) Returns rVar
               If rVar
                  
                  ; Set the method text.
                  Calculate Text as con("Calculate iRow.",rCol().$name," as pfValue")
                  Calculate Text as con(Text,kCr,"Quit method kTrue")
                  Do rMethod.$methodtext.$assign(Text)
                  
               End If
            End If
         End If
      End If
   End If
   
   ; Next column
   Do iRow.$cols.$next(rCol) Returns rCol
   
End While

Quit method FlagOK

With this code in place, you simply add a new column to the sConstants_listdef schema class, and the next time you initialize the oConstants object, the getter and setter methods are added for you.