Skip to content

LotusScript Classes Deep Dive Part One

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?

In Java, all code has to be in classes. However, for our languages, like in Visual Basic or JavaScript, functions can be outside of classes and called just using the function name. This means you don't have to create classes as often, particularly in Domino where you will typically be running server-based functions in agents or triggering functions from events. And when interacting with data and resources, the in-built classes of lsxbe (Notes... classes) and lsxui (NotesUI... classes) provide adequate object-based support for many. But a Class is basically a template for how you will interact with individual data items as a related collection of variables, instead of just using unrelated variables. Consider the following code.

Dim firstName as String
Dim lastName as String
Dim age as Integer

You could repeat 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:

  1. The functions are stored with the class they act upon.
  2. 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.

Scoping

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.

Members

The class can contain:

  • Variables
  • Properties
  • Subs
  • Functions

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

Any developer who has worked with Java or JavaScript understands what properties are, the terminology is used for what LotusScript refers to as member variables. And they work exactly the same in LotusScript, the same as member variables. But there are particular reasons to use them:

  • 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

Each function name must be unique. The same function name cannot be used for different sets of parameters. That is possible if the class is written in an LSX, but not possible if the class is written in LotusScript / VoltScript. Classes can be overloaded in Java, JavaScript or Visual Basic, but not in LotusScript / VoltScript.

The other difference is that subs or functions in LotusScript / VoltScript can not have optional parameters. Again, that is an option in Java, JavaScript and Visual Basic.

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

The 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.

Domino Class documentation

Domino Property Get / Set

Visual Basic Class documentation