Tech Tip: Implementing Simple Singleton Properties
PRODUCT: 4D | VERSION: 20 R5 | PLATFORM: Mac & Win
Published On: August 20, 2024
Singletons are a powerful and useful feature introduced in 4D 20R5. The feature combines the concepts of classes and Storage/Shared Objects/Shared Collections.
Like Storage, a singleton can be unique but shared across the entire instance of the application. Since singletons are designed to be preemptive capable, it uses the similar mechinisms to Storage. If a property is defined in a singleton, it cannot be directly written to without using the Use...End use structure.
For example with the following singleton class:
// Singleton Class: sgtn_Example property myProperty : Text shared singleton Class constructor() This.myProperty:="Default" |
Then calling the following method:
$result:=cs.sgtn_Example.me.myProperty cs.sgtn_Example.me.myProperty:="Hello World!" |
The $result variable is properly assigned "Default". But the second line of code generates a Syntax error complaining that the shared object needs the Use...End use structure:
One solution is to follow the error message and apply the Use...End use Strucutre:
Use (cs.sgtn_Example.me) cs.sgtn_Example.me.myProperty:="Hello World!" End use |
Another solution is to configure the class to utilize computed attributes with shared functions and hidden properties.The previous singleton class can be updated to the following:
// Singleton Class: sgtn_Example property __myProperty : Text shared singleton Class constructor() This.__myProperty:="Default" shared Function set myProperty($in_t : Text) This.__myProperty:=$in_t shared Function get myProperty() : Text return (This.__myProperty) |
The property is set to a hidden property by utilizing the double underscore ("__") prefix. Then a computed attribute that simply represents the property can be created based on the original property name without the hidden underscore but utilizing the shared keyword. The shared keyword is a feature of singleton that automates the Use.End use call without needing to add it to the code.
With the class updated it can be called in the following and more eleagant manner by dirrectly modifying the "property" without needing to directly add in the Use...End use statement:
cs.sgtn_Example.me.myProperty:="Hello World!" $result:=cs.sgtn_Example.me.myProperty |
The name of the property and the computed attribute (setter and getter) do not have to be similar, and the property does not have to be hidden. Hidding the property allows the autocomplete to not suggest the propety and using similar names makes the relation of the two more obvious when reading the class.
The property and computed attribute cannot share the same name like in the following:
property myProperty : Text //... shared Function set myProperty($in_t : Text) This.myProperty:=$in_t |
as when the property set a value it will call the setter, which will attempt to perform the asignment which will then cause an infinite recursive call to the setter that will lock up the application.
Utilizing the suggestion of shared computed attributes dirrectly associated with properties, simple singleton properties can be implemented to write code in a simplified manner.