Protocols
Class Interface
A class has two parameters:
viMethod is used to pass the method to be executed by the class. The method is passed to the class as a parameter and is directly assigned to the attribute structure to improve readability and ensure upward compatibility. This notation is similar to other object-oriented languages that reference methods using the dot notation; e.g. customer.add().
viSelf is used to pass the calling class base name. Passing this name allows a super-class that inherits a method to call or access the attributes of the subclass for run-time inheritance.
The base name is the name of the logical class. For example, the logical class CustomerTableUI is implemented as zCustomerTableUI (the class) and aCustomerTableUI (the attribute structure) in Zim.
Please review Section 3.6 for an example of run-time inheritance.
The message to an object consists of:
• data values assigned to the attribute structure
• any named sets
• the class call
• method
• self parameter
Class interface consists of the following:
Name | Description | Example |
Class Name | The name of the class. | zCustomer |
Method | The method to be executed. | add |
Self | The child class. | Refer Section 3.6. |
Attribute Structure | The attribute structure associated with the class. | aCustomer |
Named Set | The named set associated with the class. | sCustomer |
The interface of a Zim class is:
classname(method, self)
An example call to a Zim class:
zCustomer(‘add’,”)
Note: Self is only used for inherited calls, not delegated requests. Please refer to the Inheritance section.
4.1.2 Method Interface
4.1.2.1 Public Methods
Other classes and the owning class can call a public method. Methods are defined in the method dispatcher.
The interface of a public method:
method(self)
An example call to a Zim class:
mAdd(viSelf)
4.1.2.2 Private Methods
The owning class can only call a private method. Private methods can have any number of parameters.
The interface of a private method:
method(<<param>>)
An example of call to private method:
mpGetStatus(viStatus, voMessage)
4.1.3 Exception Handling
Exceptions are passed via the standard exception attribute oException (e.g. aCustomer.oException).
To throw an exception, a string is assigned to the oException attribute and the ’set exception error’ is executed.
method mAddItem (viSelf)
% Some processing here %
if $lastmember(‘sShoppingCart’) = 0
change aMakeAnOrder \ let oException = ‘noShoppingCartToUpdate’ set exception error endIf % Some more processing here %
endMethod % mAddItem
The client class catches the exception (i.e. the class that called the class that threw the exception). The code that catches all exceptions is as follows:
method mCallMakeAnOrder (viSelf)
% Assign attributes here % zMakeAnOrder(’addItem’,’’)
if (let aMakeAnOrder.oException = aShoppingCart.oException) > ” set exception error endIf
endMethod % mCallMakeAnOrder
The code that catches specific exceptions is as follows:
method mCallMakeAnOrder (viSelf)
% Assign attributes here % zMakeAnOrder(’addItem’,’’)
if (let aMakeAnOrder.oException = aShoppingCart.oException) = \ ‘noShoppingCartToUpdate’ % do something specific % endIf
endMethod % mCallMakeAnOrder
Naming Conventions
Item | Prefix | Suffix | Example | Notes |
Class Items | ||||
Class Business | z | zCustomer | 1, 3 | |
Class User Interface | z | UI | zCustomerUI | 2, 3 |
Method | m | mOpen | ||
Constructor Method | mp | mpCustomer | ||
Finalize Method | mpFinalize | |||
Method Private | mp | mpAutoIncrement | 4 | |
Method External | z | <method> | zCustomerAdd | 3 |
Attribute Structure | a | aCustomer | ||
Attribute Field Name Input | i | iAutoIncrement | ||
Attribute Field Name Output | o | oStatus | ||
Attribute Field Name Input/Output | <none> | FirstName | ||
Attribute FieldName Private | p | pMethod | ||
Parameter Input | vi | viMethod | ||
Parameter Output | vo | voKey | ||
Parameter Input/Output | vt | vtFirstName | ||
Parameter Local | vl | vlIsConnected |
Zim Objects | ||||
Constant | c | cBlue | ||
Directory | <none> | Framework | ||
Display | d | dCustomer | ||
Document Structured | ds | dsCustomer | 5 | |
Document Unstructured | du | duCustomer | 5 | |
Entity | <none> | Customer | ||
Field | <none> | FirstName | ||
Form | f | fCustomer | ||
Menu | mn | mnCustomer | ||
Menu Item | mi | miSave | ||
NamedSet | s | sCustomer | ||
Relationship | <none> | Require | ||
Role | <none> Cust | |||
Variable | v | vSetting | ||
Window | w | wCustomer | ||
Non-data Form Fields | 6 | |||
Push Button | pb | pbCancel | ||
Scroll Bar | sb | sbCustomer | ||
Frame | fr | frGroup | ||
Image | im | imPhoto | ||
Arrays implemented with forms and displays |
Form | i | iTabControl | Item or instance | |
Display | r | rTabContorl | Array structure |
4.2.1 Notes
1. Tables are named with a singular noun. The business class name that encapsulates a table(s) is a concatenation of the letter “z” and the table or named set name. The filename would have a “.z” file type e.g. customer.z
2. The user interface class filename would have a “.zui” file type e.g. customer.zui
3. Class names should be as short as possible and not more than 15 characters (including the “z”). This will leave a space for a type suffix e.g. zCustomerUI or a method name on an externalised method e.g. zCustomerPrint.
4. Private methods can have variable number of parameters.
5. It is recommended to use these prefixes for data storage documents. For example, an entity set Customer requires a temporary data storage document that is named duCustomer. Filenames for structured and unstructured documents are “.ds” and “.du” respectively. There may be times where a developer needs to use a document for persistent storage rather than an entity set. It would be permissible to omit the prefix in this case.
6. Prefixes are used for form fields that do not represent data attributes. For example the save button is labelled pbSave, not the prefix ”pb”. The form field firstName, which represents an attribute of Customer, has no prefixed.
Layout and Style
Feature | Rule |
method dih | The structure of a method dispatcher follows this template: |
dispatcher | Class z<ClassName>(viMethod, viSelf) mp<ClassName>(viMethod, viSelf) case when a<ClassName>.pMethod = ’method1’ m<Method1> when a<ClassName>.pMethod = ’method2’ m<Method2> endCase mpFinalise(viSelf) endClass the method name in the case statement matches the |
case | Zim commands, functions and system variables are in mixed case with the first alphabetic character in lower case
quitTransaction $currentMember(‘sCustomer’) $setCount object names are in mixed case with the first alphanumeric character upper case; name prefixes are in lower case FirstName mpAutoIncrement aCustomer method names are in mixed case with the first alphabetic character in lower case where aCustomer.Method = ’setCreditLimit’ |
breaking and indenting lines | use spaces, not tab characters
indent 2 spaces (or logical multiples of) e.g. lining up components of a let statement requires 4 spaces let aCustomer.FirstName = ‘Gordon’ \ subcommands start on a new line find all Customer Buy Product \ |
sorted by ProductName \ keep Product \ evaluate (let vlTotal = $total(Price)) \ -> sProduct subcommands in set specifications are indented 4 spaces find all Customer \ when boolean expressions are broken, try to indent by logic find 1 Customer \ code in a class or local class is indented the local variable declaration is indented on/endon exception handler statements are not indented method mpCalculateTotal(voTotal) \ |
|
quoting | use single quotes, except where double quotes are required
when aUI.iMethod = ‘Add’ quote character strings let aCustomer.LastName = ‘Lightfoot’ |
spacing | no spacing before the parentheses on class or function calls
zCustomer(‘add’, ‘CustomerUI’) $trim(LastName) |
one space after evaluate subcommand
compute 1 Customer \ one space before a parentheses in a operator, no space after evaluate (let vlCredit = Credit + (5 * Level)) single space surrounding operators if vlSum > (5 * 3 + (4 + vlAmount)) single space after each comma in a call or list $concat(‘Roch’, ‘ ‘, ‘Voisine’) LastName in (‘Morissette’, ‘Murray’, ‘Dion’, ‘Lang’, ‘McLachlan’) single space before the line continuation backslash find 1 Customer \ |
Abbreviation Rules
Currently Zim limits the name of an object to 18 characters. With the addition of prefixes this can reduce the root of the object name 15-17 characters. This section specifies how to obtain a meaningful object name when shortening an identifier that exceeds this limit.
Abbreviation Guide
Apply each question to the word that you are trying to shorten until a readable abbreviation is identified [McConnell 93].
• Does a standard abbreviation exist? – check the dictionary.
• Can nonleading vowels be removed? (Customer becomes Cstmr, Product becomes Prdct, Order becomes Ordr)
• Can an acronym be created?
• Can each word be reduced to three or less letters?
• Can suffixes be removed? – such as ing, ed.
• Can the word be reduced to the first and last letters?
Translation Descriptions
To clarify abbreviations a translation description is invaluable. The translation is stored in DDDescriptions for an object defined in the Object Dictionary. For parameter names, a translation is incorporated in description of the parameter name in the ”@param” sequence.
%
% @param CstmrID the Customer ID is a unique identifier
% for the Shopping Cart
%
For more information on documentation please refer to the next section.