Classes have always been a part of LotusScript, an aspect used heavily in many open source projects. Recently I came across an OpenNTF project OpenDOM, which not only includes a number of sophisticated classes and design patterns in its design, but also in the UI covers a variety of projects that provide Object Oriented extensions for Domino. Unfortunately, the project seems to be one of many on OpenNTF that have become unsupported, and many of the projects it points to have either been lost or are unsupported. With so few people in the community covering these kinds of development topics in blogs or conference sessions, I wonder how much knowledge on more advanced topics has been lost. Indeed over the last few years I have also learned things about LotusScript that I did not know before, as I have had to create more sophisticated LotusScript / VoltScript functionality. So this blog series is intended to explicitly share some of that knowledge, specifically relating them to experience of other languages.
To give some context, everything that will be covered about LotusScript will also be relevant for VoltScript, although there may be additional functionality available.
What Is A Class?
Dim firstName as String Dim lastName as String Dim age as Integer
You could repeate those variables for every function where you wish to use them. Or you could create a Class.
Class Person Public firstName as String Public lastName as String Public age as Integer End Class
Classes are more effort. But if the variables are related and repeated, typically there are functions you need to run that are also repeated and related. The Class gives two obvious benefits:
- The functions are stored with the class they act upon.
- The functions have direct access to the variables they need to use.
There is a variety of tooling opportunities that can also help make Classes more attractive. IDEs can provide some of that or, with the code as text files, any developer could contribute such functionality with imagination and code conventions.
Classes and Class members (variables, subs, functions, properties) have a scope. LotusScript / VoltScript provides two options - Public or Private. Public means they are accessible within the current script file or any that references it. Private means they are only accessible within the current context. For a Class that means it is only accessible from the current script file. For Class members (variables, subs, functions, properties) that means within the current Class.
The default scoping can be managed with the
Option keyword, and Domino Designer now automatically adds
Option Public to Agents and Script Libraries.
Other languages have other modifiers. Java has Protected, which means a class is accessible to other classes that are siblings. Visual Basic has Protected, Friend, Protected Friend and Private Protected. There are also a variety of other keywords relevant to classes, like Shadows, MustInherit and NotInheritable. But LotusScript / VoltScript retains a less complex set of options and this simplicity arguably ensured the language was more accessible to developers who did not come from a Computer Science background.
The class can contain:
Visual Basic and Java allow nested classes, so a Class can contain the definition for another class. That is not the case in LotusScript or VoltScript.
All can be scoped by being prefixed with the keywords Public or Private. Variables must be prefixed with Public or Private, for other members it is optional. However, bear in mind that based on my testing, if a Class is Public, then properties, subs and functions contained within it are by default public. This is actually consistent with what Visual Basic also does, according to its documentation.
Variables, Subs and Functions are well known to any LotusScript developer. Properties are probably less well-known, but are quite simple.
- Properties can be getters, setters or both. This means you can make them Read Only, Write Only or Read-Write. Of course a read-write property works exactly the same as a variable.
- Properties can take parameters
A property that takes parameters does not have an obvious use case. The example in the documentation allows an increment to be passed. I’ve not used a Property Set with parameters and I don’t remember seeing one. The other thing to bear in mind when using properties is that the getter and setter need to take the same parameters.
However, the option to make properties read only or write only is particularly useful, and I’m sure developers can think of good use cases for that. There is an easy one to demonstrate with our Person class.
Class Person Public firstName as String Public lastName as String Public age as Integer Public Property Get fullName as String fullName = Me.firstName & " " & Me.lastName End Property End Class
As ever with Domino, there are multiple ways to achieve the same outcome, and many developers may typically return a full name by using a function. But using a property makes a neater approach. As we move forward into the world of VoltScript, I can also see other valid use cases for properties.
When it comes to a Property Set, the important thing to bear in mind with the syntax is that the developer does not explicitly name a parameter that the setter receives. The parameter it receives is the name of the property itself.
Private storedFullName as String Public Property Set fullName as String Me.storedFullName = fullName End Property
This also demonstrates that the property name (“fullName”) cannot also be used for a variable. The variable (“storedFullName”) needs to be different.
Subs and Functions
This can provide some limitations, particularly in certain circumstances. But in most scenarios, with a little imagination, it is possible to work around it.
Delete sub is a special procedure automatically called when the runtime deletes an instance of this class. When that happens will depend on the scope of the instance. But this can be used to run special functionality. In Volt MX LotusScript Toolkit I used this technique for two useful purposes - erasing Lists that were member variables and calling the
closeRequest() sub to send the HTTP response. These are probably the most common use cases for code in the Delete sub.
Referencing the Class Instance
This code demonstrates a final point about classes for this blog post - referencing the current instance of the class. The keyword
Me can be used to reference variables, properties, functions and subs in the current class, although Domino Designer does not enforce this convention.