PML
(Programmable Macro Language)
Manual
Description: This manual describes the AVEVA PDMS PML language.
Purpose: As source materials have been used internal AVEVA guide lines
supplemented with references from AVEVA world forum web page and other web pages. This manual has no copyrights and it was created only for educational purposes. All data are only informative.
Inscription: All self-educated users please feel free to use and improve your own skills. Sharing your knowledges could improve our community and it could change the world in the result.
CONTENT
CONTENT ... 2
1. PML - PROGRAMMABLE MACRO LANGUAGE ... 9
1.1. CUSTOMIZING A GRAPHICAL USER INTERFACE... 10
1.2. NOTE FOR USERS FAMILIAR WITH OOCONCEPTS ... 10
2. PML VARIABLES ... 11
2.1. PML2 VARIABLES ... 11
The built-in object types ... 11
2.1.1. The system-defined object types... 12
2.1.2. The user-defined object types ... 12
2.1.3. 2.2. CREATION OF VARIABLES ... 13
2.2.1. PML1 variables creation ... 13
2.2.2. PML2 variables creation ... 13
2.3. MEMBERS AND ATTRIBUTES... 14
2.4. NAMING CONVENTIONS ... 15
3. PML EXPRESSIONS ... 17
3.1. PML1 EXPRESSIONS ... 17
3.2. PML2 EXPRESSIONS ... 17
3.3. CREATING UNSET AND UNDEFINED VARIABLE ... 18
3.4. DELETING PMLVARIABLES ... 18
3.5. MIXING OF THE VARIABLES TYPES ... 18
3.6. EXPRESSION OPERATORS ... 19
3.7. BOOLEAN OPERATORS... 20
3.8. CONCATENATION OPERATOR ... 20
3.9. COMMUNICATING WITH AVEVAPRODUCTS IN PML... 21
3.10. PARAMETERIZED MACROS ... 21
3.11. SYNONYMS ... 21
3.12. CREATING OTHER TYPES OF VARIABLE ... 22
3.13. USING THE MEMBER VALUES OF AN OBJECT ... 22
3.14. PMLFUNCTIONS AND METHODS ... 22
3.15. STORING AND LOADING PMLFUNCTIONS... 23
3.16. ARGUMENTS OF TYPE ANY ... 23
3.17. PMLPROCEDURES ... 24
3.18. USING THE METHODS OF AN OBJECT ... 25
3.19. METHODS ON USER-DEFINED OBJECT TYPES... 25
3.20. METHOD OVERLOADING ... 26
3.21. CONSTRUCTOR METHODS WITH ARGUMENTS ... 26
3.22. OVERLOADING WITH ANY ... 27
3.23. INVOKING A METHOD FROM ANOTHER METHOD ... 27
3.24. DEVELOPING A PMLOBJECT WITH METHODS ... 27
3.25. FORMS AS GLOBAL VARIABLES ... 27
4. ARRAYS IN PML ... 28
4.1. ARRAY METHODS... 29
4.2. SORTING ARRAYS USING THE VARCOMMAND ... 31
5. COLLECTIONS ... 32
5.1. THE COLLECTION SYNTAX PML1 ... 32
5.2. THE OBJECT COLLECTION SYNTAX PML2 ... 32
5.3. THE COLLECTION EXAMPLES ... 32
5.4. ARRAY SORTING ... 35
5.4.1. PML 1 array sorting ... 35
6. PML GENERAL FUTURES ... 38
6.1. FUNCTIONS,MACROS AND OBJECT DEFINITIONS ... 38
6.2. COMMENTS IN PMLFILES ... 38
6.3. LEAVING A PMLFILE WITH THE RETURNCOMMAND ... 38
6.4. CASE INDEPENDENCE ... 38
6.5. ABBREVIATIONS... 39
6.6. SPECIAL CHARACTER $ ... 39
6.7. TEXT DELIMITERS ... 39
6.8. FILENAME EXTENSIONS ... 40
6.9. STORING AND LOADING PMLFILES ... 40
6.10. REBUILDING ALL PMLFILE INDEXES ... 40
6.11. QUERYING THE LOCATION OF PMLFILES ... 40
7. PML CONTROL LOGIC ... 41
7.1. IFCONSTRUCT ... 41
7.1.1. Nesting if-constructs ... 41
7.1.2. IF, THEN, ELSEIF and ELSE Statements ... 42
7.1.3. BOOLEAN Expressions and if Statements ... 42
7.1.4. IF TRUE Expression ... 43
7.1.5. Boolean expressions PML1 upward compatibility ... 43
7.2. DOLOOPS ... 44
7.2.1. Stopping a DO loop: break and breakif ... 44
7.2.2. Skipping Commands in a DO Loop using Skip or Skip if... 44
7.2.3. Nested DO Loops ... 45
7.2.4. DO Index and DO Values ... 45
7.2.5. DO Loops Examples ... 45
7.2.6. DO Values with Arrays of Objects ... 46
7.3. JUMPING TO A LABELLED LINE ... 46
7.3.1. Conditional Jumping to a Labelled Line ... 46
7.3.2. Illegal Jumping ... 47
7.4. ERRORS AND ERROR HANDLING ... 47
7.4.1. Error Conditions ... 47
7.4.2. Handling Errors ... 47
7.4.3. Setting the ONERROR Behavior... 48
7.4.4. Other Responses to an Error ... 48
7.5. HANDLING FILES AND DIRECTORIES ... 49
7.5.1. Creating a File Object ... 49
7.5.2. Reading from Files ... 50
7.5.3. Writing to Files... 50
7.5.4. Reading and Writing ARRAYS ... 50
7.5.5. Error Handling When Using a File Object ... 50
8. MACROS ... 51
8.1. PMLMACROS ... 51
8.1.1. Naming and Running Macros... 51
8.2. USING MACROS AND FUNCTIONS TOGETHER ... 52
8.3. SYNONYMS IN PMLMACROS AND FUNCTIONS ... 52
8.4. PML1HIERARCHY... 53
8.5. PML2FUNCTIONS AND OBJECTS ... 53
8.5.1. The pmllib environment variable ... 53
8.5.2. Modifications to pmllib ... 53
8.5.3. Updating PDMSUI and PMLLIB ... 54
8.5.4. PML2 Objects ... 54
8.5.5. PML2 Methods ... 54
8.5.6. Method Concatenation... 55
8.5.7. The !!CE Object ... 55
8.5.8. PML2 Functions ... 56
9. USING PML IN AVEVA PRODUCTS... 57
9.1. COMPOSING TEXT ... 57
9.2. DEFINING VARIABLES FOR LATE EVALUATION (RULES) ... 57
9.3. USING PML IN PDMS ... 58
9.3.1. Accessing DB Elements As Objects ... 58
9.3.2. Assigning Values to Element Attributes ... 58
9.3.3. Accessing Information About a Session ... 59
9.3.4. Evaluating Selected DB Elements... 59
9.3.5. RAW keyword When setting Variables with VAR... 60
9.3.6. Undo and Redo ... 60
10. COPIES AND REFERENCES ... 61
10.1. ASSIGNMENT ... 61
10.2. FORM AND GADGET REFERENCES ... 61
10.3. DBREFERENCES ... 61
10.3.1. Deep Copy involving References: ... 61
10.4. FUNCTION ARGUMENTS ... 62
10.4.1. Constants as Function Arguments ... 62
10.4.2. Form and Gadget Properties Passed as Function Arguments ... 62
10.5. DATABASE ATTRIBUTES ... 62
11. DEVELOPING PML CODE ... 63
11.1. USING UNICODE TEXT ... 63
11.1.1. Textual File Handling ... 63
11.1.2. File Transcoding Utility ... 64
11.1.3. Using Unicode as the new PDMS Internal Format ... 64
11.2. PMLTRACING ... 65
11.3. DIAGNOSTIC MESSAGES FROM WITHIN PMLFILES ... 65
11.4. ALPHA LOG ... 65
11.5. ALPHA LOG AND PMLTRACING ... 65
11.6. SUSPENDING A RUNNING PMLMACRO ... 65
11.7. QUERYING PML ... 66
11.7.1. Querying the Currently Running PML File Stack ... 66
11.7.2. Querying the Values of PML Variables ... 66
11.7.3. Querying What Can Be Typed Next ... 66
12. UPGRADING FROM PML1 TO PML2 ... 67
12.1. DIFFERENCE BETWEEN PML1 AND PML2 ... 67
12.1.1. PML1 advantages... 67
12.1.2. PML2 advantages... 67
13. PML FORM CONCEPTS ... 70
13.1. OVERVIEW ... 70
13.2. NAMING FORMS AND THEIR MEMBERS ... 70
13.3. SIMPLE FORM ... 71
13.3.1. Adding a Gadget Callback ... 71
13.4. FORM DEFINITION FILE... 72
13.5. HOW FORMS ARE LOADED AND DISPLAYED ... 72
13.6. PMLDIRECTIVES ... 73
13.7. REVISITING OUR SIMPLE FORM ... 74
14. FORMS AND GADGET CALLBACKS ... 76
14.1. CALLBACKS:EXPRESSIONS... 76
14.2. CALLBACKS:FORM METHODS /PMLFUNCTIONS... 76
14.3. PMLOPEN CALLBACKS ... 77
14.3.1. Events ... 77
14.3.2. Open Callbacks at Meta-events ... 77
14.3.3. Using a PML Function in an Open Callback ... 79
14.3.4. Objects That Can Have Open Callbacks ... 79
15. FORMS ... 80
15.1. MODULES AND APPLICATIONS... 80
15.2. DEFINING A FORM ... 80
15.2.1. Form Attributes ... 80
15.2.2. Form Type ... 81
15.2.3. Layout Modes ... 81
15.2.4. Minimum Size and Resizability ... 82
15.2.5. Intelligent Resizable Forms ... 82
15.2.6. Gadget Alignment Control... 82
15.2.7. No Alignment ... 82
15.3. FORM MEMBERS ... 83
15.3.1. Form Title and Icon Title ... 83
15.3.2. Form Initialisation Callback ... 83
15.3.3. Form OK and CANCEL Callbacks... 83
15.3.4. Quit/Close Callback ... 84
15.3.5. FIRSTSHOWN callback ... 85
15.3.6. KILLING callback ... 85
15.3.7. Form Variables: PML Variables within a Form ... 85
15.3.8. Querying Form Members ... 86
15.4. LOADING,SHOWING, AND HIDING FORMS ... 86
15.4.1. Free Forms and Form Families ... 86
15.4.2. Loading and Showing Forms ... 87
15.4.3. Position of Forms on the Screen ... 87
15.4.4. Hiding Forms ... 88
15.4.5. Killing Forms... 88
15.4.6. NOQUIT Form Status ... 88
16. MENUS ... 89
16.1. MENU TYPES AND RULES... 89
16.2. DEFINING A BAR MENU GADGET ... 89
16.2.1. Defining a Menu Object ... 90
16.2.2. Window Menu... 91
16.2.3. Online Help Menu ... 91
16.2.4. Popup Menus ... 91
16.2.5. Finding Who Popped up a Menu ... 92
16.3. EDITING BARS AND MENUS ... 93
16.3.1. Inserting Menus into a Bar ... 93
16.3.2. Inserting New Menu Fields ... 93
16.3.3. Changing the State of Menufields ... 94
16.3.4. Implied Menu-field Groups ... 95
16.3.5. Creating Menus Dynamically ... 96
17. FORM LAYOUT ... 97
17.1. SYSTEM FONT AND UNICODE CHARACTERS ... 97
17.2. LAYOUT MODES ... 97
17.3. CONTAINERS,GRID CO-ORDINATES AND GADGET BOXES ... 98
17.4. POSITIONING,ALIGNMENT AND SIZE OF GADGETS ... 99
17.5. AUTO-PLACEMENT ... 100
17.5.1. Positioning Gadgets on a Defined Path ... 100
17.5.2. Setting the Auto-displacement between Gadgets ... 100
17.5.3. Gadget Alignment ... 101
17.5.4. How It All Works ... 101
17.5.5. Default Positions in Gadget Containers ... 102
17.6. RELATIVE PLACEMENT USING THE AT-SYNTAX ... 102
17.6.1. Positioning Relative to a Previous Gadget ... 102
17.6.2. Positioning Relative to the Form Extremities ... 103
17.7. MIXING AUTO AND RELATIVE PLACEMENT ... 104
17.8. ABSOLUTE GADGET POSITIONING ... 104
17.9. ATSYNTAX... 104
17.10.GADGET SIZE MANAGEMENT ... 105
17.10.1. Tag Width ... 105
17.10.2. The Meaning of Size for the PML Gadget Types ... 106
17.10.3. Specifying Gadget Size Relative to a Previous Gadget ... 106
17.10.4. Gadget Size Syntax ... 106
17.11.INTELLIGENT POSITIONING AND RESIZING ... 107
17.11.1. ANCHOR Attribute ... 107
17.11.2. DOCK Attribute ... 108
17.12.USEFUL FORM LAYOUT QUICK CHECKLIST ... 108
18. FRAME... 109 18.1. TYPES OF FRAME ... 109 18.1.1. Normal Frames... 109 18.1.2. Tabset Frames ... 109 18.1.3. Toolbar Frames ... 109 18.1.4. PANEL Frames ... 109
18.1.5. Fold Up Panel Frames ... 109
19. GADGETS AND THEIR ATTRIBUTES... 110
19.1. GADGET DEFINITION COMMANDS ... 110
19.2. SOME GENERIC GADGET MEMBERS AND METHODS... 111
19.3. GADGETS THAT SUPPORT PIXMAPS ... 111
19.3.1. Selected and Unselected States ... 111
19.3.2. AddPixmap Method ... 111
19.4. DE-ACTIVATING GADGETS:GREYING OUT ... 112
19.4.1. Greying Out Gadgets on Forms ... 112
19.5. MAKING GADGETS VISIBLE AND INVISIBLE ... 112
19.6. SETTING KEYBOARD FOCUS ... 113
19.7. REFRESHING GADGETS... 113
20. GADGET SET ... 115
20.1. EXAMPLES ... 115
20.1.1. Complex Form Layout ... 115
20.1.2. Multi-lingual Form ... 121
20.2. FRAME GADGETS ... 123
20.2.1. Defining a Frame ... 123
20.2.2. Frame Radio Groups ... 123
20.2.3. Managing Pages in Tabset Frames... 125
20.2.4. Managing the Fold Up Panel... 126
20.3. CONTAINERGADGET ... 127
20.3.1. Example of Container Gadget ... 127
20.4. PARAGRAPH GADGETS ... 129
20.4.1. Textual Paragraph Gadgets ... 129
20.4.2. Pixmap Paragraph Gadgets ... 130
20.4.3. Textual Paragraph Gadgets ... 130
20.5. BUTTON GADGETS ... 130
20.5.1. Buttons of Type Toggle ... 130
20.5.2. Buttons of type LINKLABEL ... 131
20.5.3. Form Control Attributes ... 131
20.5.4. Defining a Dismiss Button ... 132
20.6. TOGGLE GADGETS ... 132
20.7. RTOGGLE GADGETS ... 132
20.8. OPTION AND COMBOBOX GADGETS ... 134
20.8.1. Textual Option Gadgets ... 134
20.8.2. Combobox Gadgets ... 135
20.8.3. Pixmap Option Gadgets ... 135
20.8.4. Setting and Getting the Current Selection ... 135
20.9. SLIDER GADGETS ... 136
20.10.LINE GADGETS ... 136
20.11.NUMERIC INPUT GADGET ... 137
20.12.LIST GADGETS... 137
20.12.1. Single Choice List Gadgets ... 138
20.12.2. Multiple Choice List Gadgets ... 139
20.12.3. Multi-Column List Gadgets ... 141
20.13.DATABASE SELECTOR GADGETS ... 142
20.14.TEXT GADGETS ... 143
20.14.1. Controlling Text Gadgets’ Editing ... 144
20.14.2. Copying and Pasting into Text Fields ... 145
20.14.3. Formatting in Text Input Gadgets: Imperial Units ... 145
20.14.4. Unset Text Fields ... 146
20.14.5. Validating Input to Text Fields ... 147
20.14.6. Setting the Value of a Text Field ... 148
20.15.TEXTPANE GADGETS ... 148
20.15.1. Fixed Width Font... 150
20.16.FAST ACCESS TO LISTS,SELECTORS AND TEXTPANES USING DOLOOPS ... 151
20.17.VIEW GADGETS ... 151
20.17.1. Defining a View Gadget ... 152
20.17.2. Resizable View Gadgets ... 152
20.17.3. Pop-up Menus in Views ... 152
20.17.4. Defining Alpha Views ... 152
20.17.5. Graphical Views ... 154
20.17.6. Defining PLOT Views ... 156
20.17.7. Defining DRAFT’s Area (2D) Views ... 156
21. FMSYS OBJECT AND ITS METHODS ... 160
21.1. MANAGING THE DEFAULT FORM LAYOUT MODE ... 160
21.2. SWAPPING APPLICATIONS ... 160
21.3. PROGRESS AND INTERRUPT METHODS... 160
21.4. REFRESHING VIEW GADGETS ... 161
21.5. CHECKING REFERENCES TO OTHER FORMS ... 161
21.6. SPLASH SCREEN ... 161
21.7. DEFAULT FORM POSITIONING ... 162
21.8. CURRENTDOCUMENT()METHOD ... 162
21.9. LOADFORM()METHOD ... 162
21.10.CURSOR FUNCTION SUPPORT ... 162
21.11.SETTING THE DEFAULT FORMAT OBJECT FOR TEXT FIELDS ... 163
22. PML ADD-INS ... 164 22.1. APPLICATION SWITCHING ... 164 22.1.1. Main Form ... 164 22.1.2. Callbacks... 165 22.1.3. Defining an Add-in ... 165 22.1.4. Add-in Object... 166 22.1.5. Initialisation ... 166 22.2. MENUS ... 166 22.2.1. APPMENU Object ... 166
22.2.2. Addition of Menu Items ... 166
22.2.3. Removing Menu Items ... 167
22.2.4. Modifying the Bar Menu ... 167
22.3. TOOLBARS ... 168
22.3.1. Toolbar Control... 168
22.3.2. Removing Gadgets from a Toolbar ... 169
22.3.3. Deactivating Gadgets on a Toolbar ... 169
22.4. FORMS... 169
22.4.1. Registering a Form ... 169
22.4.2. Hiding Forms when Exiting Applications... 169
22.4.3. Storing Data Between Sessions ... 170
22.5. CONVERTING EXISTING USER-DEFINED APPLICATIONS ... 171
22.5.1. Replacement of the DBAR File ... 171
22.5.2. Menu Name Clashes ... 171
22.5.3. Converting the DBAR File ... 171
22.6. EXAMPLE APPLICATION ... 172
22.6.1. Adding a Menu Field ... 172
22.6.2. Creating a Custom Delete Callback ... 172
23. EVENT DRIVEN GRAPHICS (EDG) ... 174
24. PML.NET... 176
24.1. IMPORT AN ASSEMBLY INTO PDMS ... 176
24.1.1. PML.Net syntax ... 176
24.2. CREATING A PML FORM CONTAINING THE .NETCONTROL ... 177
24.3. GRID CONTROL ... 178
24.3.1. Applying Data to the Grid ... 178
1. PML - Programmable Macro Language
PML is a file-based interpreted language that enables an application developer to design macro files, programmable macros or Microsoft Windows form-based add-ins that can be included within an Aveva product such as Plant Design Management System (PDMS). There are currently three iterations of the PML language:
• PML1 - Basic macro / command language with Window form capabilities.
• PML2 - Advanced ver. of PML1, include object-oriented capability for forms and menus.
• PML.NET - An alternative PML mechanism to facilitate the use of Microsoft .NET controls into a PML environment.
* Macro is a group of commands written to a file. By asking PDMS to run a macro, you are really asking PDMS to run a series of commands in a set order (as defined in the macro file). * Programmable Macro is containing program constructs such as IF statements and loops. * Forms-based add-ins most applications are driven by forms and menus.
* PML Programmable Macro Language.
* PML1 First version of PML including loops, IF statements, string handling, labels etc. * PML2 Object orientated language builds on PML1 and extends the facilities to be like other object based languages (C++, Smalltalk).
The current version of PML, sometimes referred to as PML2, may simply be seen as an extension to the original PML1 facilities. However, the more powerful techniques that are available mean that many programming tasks are carried out in different ways. There are some tasks which are carried out more efficiently using PML 1 facilities. PML 2 has been specifically designed for writing and customizing the Forms and Menus for AVEVA products.
PML2 is an enhanced version of PML and is more like other modern languages that you may be familiar with. PML2 is almost an object oriented language. It provides most features of other Object Orientated Programming (OOP) languages except for inheritance. It provides for classes of built-in, system-defined and user-defined object types. Objects have members (their own variables) and methods (their own functions). All PML variables are an instance of a built-in, system-defined or user-defined object type. Both PML1 and PML2 have their advantages and disadvantages. However, PML2 has not completely replaced PML1.
Picture Nr.1. - PML File hierarchy
Typically, fewer lines of code needed with PML2 when compared to traditional PML (PML1) and it has been designed to be easier to read/write. While most PML1 macros will still run within PDMS, PML2 bring many new features that were previously unavailable. Built in methods for different variable types remove several multi line procedures used in old style macros. Use of $ characters is dramatically reduced with a more readable format for expressions.
$-style macros will still work provided the syntax has been followed correctly. It is possible to convert traditional PML code to include newer PML2 features, but it is important that users maintain compatibility at all times.
The main features of PML2 are:
• Available Variable Types - STRING, REAL, BOOLEAN, ARRAY
• Built in Methods for commonly used actions
• Global Functions supersede old style macros
• User Defined Object Types
• PML Search Path (PMLLIB)
• Dynamic Loading of Forms, Functions and Objects
• Aid objects for geometric modeling
PML is now more consistent with other programming languages and more structured in form. The new data types are now OBJECTS which can be operated by running METHODS. The old $ based variables are still valid, but are always treated as strings. Global functions are macros which can be called more like subroutines than traditional macros. e.g. a function can be called between the brackets of an IF statement and return a BOOLEAN result User-defined object types enable a group of mixed variables to be combined into packages. The resulting object can then be used as a simple variable and the separate parts set or used as attributes of the variable. Search paths and dynamic loading mean that it is no longer necessary to pre load forms or have synonyms for calling macros. A large number of new aid objects have been created so that users can do more graphical construction.
1.1. Customizing a Graphical User Interface
Most AVEVA products make use of a Graphical User Interface (GUI) to drive the software. PML 2 has been specifically designed for writing and customizing the Forms and Menus for AVEVA products. Almost all the facilities available in PML 1 and the older Forms and Menus facilities continue to function as before even if they are not documented here. Before you begin customizing a GUI, you must have a good working knowledge of the command syntax for the AVEVA product you are working with.
1.2. Note for Users Familiar with OO Concepts
PML2 is almost an object-oriented language. Its main deficiency is that it lacks inheritance. However, it does provide for classes of built-in, system-defined and user-defined object types. Objects have members (their own variables) and methods (their own functions). All PML Variables are an instance of a built-in, system-defined or user-defined object type. Operators and methods are polymorphic - what they do (their behavior) depends on the type of the variable. Overloading of functions and operators is supported for all variable types. There is no concept of private members or methods, everything is public. There are only two levels of scope for variables: Global and Local. Arguments to PML Functions are passed-by-reference with Read/Write access so any argument can potentially be used as an output argument.
Note: From PDMS12.1, all textual information in PDMS is represented as Unicode. Unicode is a computing industry standard for the consistent encoding, representation and handling of text expressed in most of the world's writing systems. Developed in conjunction with the Universal Character Set standard and published in book form as The Unicode Standard, the latest version of Unicode consists of a repertoire of more than 109,000 characters covering 93 scripts. The PML Internal Format for string data is Unicode UTF8 format. This means that all PML string variables support Unicode values. You can use Unicode characters in PML variable names, PML object form and gadget names, PML method and function names. All PML language files should either be UTF8 format with a BOM present or else strictly ASCII 7-bit (decimal 32 to 127) format.
2. PML Variables
Variables are used to store values (numbers, text, Boolean, arrays, information’s, data). PML variables are two of kinds, global and local. Global variables last for a whole session (or until you delete them). They are loaded from pmllib every time when the pml index is rebuilt, in normal way always when the PDMS starts. A local variable can be used only from within one PML function or macro. These two kinds of variable are distinguished by their names. Names beginning ‘!!’ are global; names beginning ‘!’ are local.
GLOBAL variable - !!ThisIsGLOBALvariable LOCAL variable - !ThisIsLOCALvariable
PML variable names may be any combination of letters and digits, starting with a letter, up to a maximum of 64 Unicode characters (plus the ‘!!’ or ‘!’). Names are allowed to contain a dot (.) but this is now strongly discouraged as a dot has a special meaning in PML2 as a separator between an object and its methods, and between the components of form and gadget names. Therefore NEVER use dot (.) in names and NEVER start a variable name with a number! Rather than using a dot as part of a name is recommend that you use a mixture of upper and lower case to make variable names more meaningful, for example:!!StartInUpperCase . Numbered variables are set by typing a number then value after the command VAR. VAR 1 NAME, VAR 2 ‘hello’ . The available variable numbers only go to 119 (there is no 120) and they are module dependent. For these reasons, this technique is no longer commonly used.
2.1. PML2 variables
The variables used in PML 2 are objects:
• Every object (variable) has a unique name.
• An object has a set of functions associated with it, which can be called to manipulate this data. These functions are called methods.
• Some methods change the data held by the object, some return a result derived from the data, and some methods do both.
• The data that an object can hold and the functions that are available are fixed by the object type (sometimes called the object’s class).
• Before you can create an object, the object type must have been defined. The object type definition specifies what the members and methods are for that type of object. Every PML2 variable has an object type which is set when the variable is created and remains fixed as long as the variable exists. Attempting to store a value of the wrong type in an existing variable will cause an error. The object type must exist before you can create a variable of that type. PML 2 is supplied with:
• built-in object types
• system-defined object types
• user-defined object types.
The built-in object types 2.1.1.
• STRING holds any text, including newline and multi-byte characters. In macros written with PML1 where variables are created with the VAR command, all variables are of type STRING, even when they are storing numbers.
• REAL is used for all numeric values including do loop counters. The values stored are (nearly) always in the current working units of the quantity
• BOOLEAN is used for the result of logical expressions and holds the value TRUE or FALSE (Note these are not the same as the STRING values ‘TRUE’ and ‘FALSE’).
• ARRAY holds many values of any type. An ARRAY variable can contain many values, each of which is called an array element. An Array is created automatically by creating one of its array elements.
The system-defined object types 2.1.2.
• Position, Orientation, DirE, P0, P1 …
• Bore, Hbore, Href …
• Dbref, Dbname, Dbfile … Examples:
BLOCK blocks are used to store commands for a special form of working on arrays. The block contains a list of commands and “block Evaluation” is used to perform the actions on an array
FILE file is in principle a file name, but the file object contains built in methods for working on the file.
DATETIME returns current Date and Time information
DB a DB object is an object representing a database. Can be used to interrogate information about type, team, access, claim type
DBREF a dbref object a ref to a database it has members (access, file, name, number, foreign, type, description, claim (string) and team (team))
DIRECTION a Direction object has members (direction, origin (dbref), up, east, north (real)) MDB MDB object has members (name and description, both strings)
ORIENTATION an orientation object has members (alpha (real), origin (dbref), Gamma and beta(reals))
POSITION a position object has members (origin (dbref) up, east, north (reals) PROJECT a project object has one member (evar (string))
TEAM a team object has members (name and description (reals)) USER a user object has members (access, name, description (strings)) FORMAT is a way of formatting data for example metric or imperial]
The user-defined object types 2.1.3.
You may find that the object types supplied with PML 2 are enough. However, you can define new object types if you need to. In any case, the following example may help you understand objects, their members and how they are used. It is a good idea to use upper case for object-type names, and mixed upper and lower case for variable names, the objects themselves. For example, a type might be Employee, and a variable name might be NumberOfEmployees.
define object COMPANY
member .Name is STRING
member .Address is STRING
member .Employees is REAL member .NumberOfEmpliyees is REAL endobject
The user-defined object type should by normally stored in a file with a lowercase name matching the name of the object type and a .pmlobj suffix in PMLLIB directory. PML will load a definition automatically when it is needed. Example above should have name
2.2. Creation of variables 2.2.1. PML1 variables creation
For creating variable is used VAR command. As value in variable could be used text or some attribute. As you may see there are used text delimiters to define any text as value. These delimiters could be used '' or vertical bars || as well. The most important fact is that using the VAR command always create variable as string() object. Even if you use numbers or Booleans. Of course that you can create an array by VAR command but array itself contain array members. Through command VAR you just fill an array by string elements. REMEMBER THAT VAR COMMAND ALWAYS CREATES STRING OBJECT TYPE!!! Text - as string in PML2:
VAR !PML1text 'THISisTEXT' VAR !PML1attribute1 NAME VAR !PML1attribute2 POS WRT /* Numbers - as real in PML2: VAR !x (32) VAR !y (52) VAR !z1 (!x + !y) VAR !z2 ('!x' + '!y') VAR !z3 ('$!x' + '$!y') VAR !z4 (23 * 1.8 + 32) Boolean - as Boolean in PML2: VAR !T1 TRUE VAR !F1 FALSE VAR !T2 T VAR !F2 F VAR !T3 YES VAR !F3 NO VAR !T4 Y VAR !F4 N
There are no BOOLEAN () object variables in PML1. VAR command always creates the STRING () object type.
Array - as array in PML2: VAR !ARRAY[1] 'AVEVA' VAR !ARRAY[10] NAME VAR !ARRAY[20] (12) 2.2.2. PML2 variables creation
Using the PML2 syntax you will create not only the value for variable but you automatically assign the object type according to defined data. If it is simply text, then results as string object but some data as position are already defined as some other object type. In this case the position is system defined object type therefore results as POSITION. This is the most important difference between PML1 and PML2 because PML2 is object orientated language.
String:
!PML2string = 'THISisTEXT' !PML2attribute1 = NAME
!PML2attribute2 = POS WRT /* (in PML1 will be string in PML2 position object type) Real: !x = 32 !y = 52 !z1 = (!x + !y) !z2 = ('!x' + '!y') !z3 = ('$!x' + '$!y') !z4 = (23 * 1.8 + 32) Boolean: !T1 = TRUE !F1 = FALSE !T2 = T !F2 = F !T3 = YES !F3 = NO !T4 = Y !F4 = N Array: !ARRAY = ARRAY() !ARRAY[1] = 'AVEVA' !ARRAY[2] = NAME !ARRAY[3] = 12 !ARRAY[4] = N !ARRAY[5] = TRUE
2.3. Members and Attributes
An object can contain one or more items of data referred to as its members or attributes. Each member has a name.
• STRING, REAL and BOOLEAN variables just have a value - no members.
• ARRAY variables have numbered elements, not members.
User Defined Objects can contain any variable or object type as attributes or members. Information is grouped with an object for ease of reference and standard reference. User-defined objects can also contain user-User-defined methods that will use the information stored within the object. These methods may represent a calculation, or information retrieval. After an object has been declared as a variable, the methods can be applied to the variable. For example:
define object ELEMENT member .Type is STRING member .Material is STRING endobject
define method .FullDesc() is STRING return !this.Type & ‘ ‘ & !this.Material endmethod
Once a variable is declared as an ELEMENT object then the method can be applied. !item = object ELEMENT()
!Item.Type = |Flange|
!Item.Material = |Carbon Steel| !name = !item.FullDesc()
A method with no arguments but the same name as the type of the object is called the default constructor method. More than one method can be given the same name as the object, provide only one has no arguments. The following lists the methods available to all objects. The list gives the name of each method and the type of result you get back from it. The third column of the table describes what the method does.
Name Result Purpose
Attribute( 'Name') ANY To set or get a member of an object, providing the member name as a STRING.
Attributes() ARRAY OF STRINGS To get a list of the names of the members of an object as an array of STRING.
Delete() NO RESULT Destroy the object - make it undefined EQ(any) BOOLEAN Type-dependent comparison
LT(any) BOOLEAN Type-dependent comparison (converting first to STRING if all else fails)
Max(any) ANY Return maximum of object and second object Min(any) ANY Return minimum of object and second object NEQ(any) BOOLEAN TRUE if objects do not have the same value(s) ObjectType() STRING Return the type of the object as a string
Set() BOOLEAN TRUE if the object has been given a value(s) String() STRING Convert the object to a STRING
Unset() BOOLEAN TRUE if the object does not have a value 2.4. Naming conventions
Use a naming convention to avoid 'polluting the namespace’ of global variables. All global names beginning with the letters CD are reserved for AVEVA system use. Note: The most recent AVEVA Application ware (AppWare) does not use a prefix. When creating new PML Macros you are responsible for avoiding name-clashes, for example, by using your own prefix. Here are some guidelines on naming variables:
• Use each variable for one purpose only and give it a meaningful name.
• Limit your use of global variables.
• Where possible use PML object methods and Form methods instead of PML functions and macros so as to make use of their members and methods which do not global variables.
• Remember that within the methods of PML Objects and Forms you generally need only local variables. Any values which are to be exported should be made available as members or as method values or returned arguments.
• Only use PML Functions (necessarily global) for tasks which are genuinely globally accessible, i.e. independent of a specific object or form, or which need to be shared by several objects or forms.
Note: Do not use these prefixes for global or local variables. These prefixes are already used by other applications.
Application Prefix Comments Area BasedADP !!ABA Add-in application Administration !!ADM Plus !!CDA
Application Switching !!APP
Batch Handling !!BAT
CADCentre !!CADC
Draft !!CDR
Draft Icon Location !!CD2D Icon pathnames
Defaults !!DFLTS
General !!CDC Plus !!CDD, E, F, G, H, I, L, M, N, P, S, U, V, W
Specialized !!CE Plus !!ERROR, !!FMSYS
The majority of the existing PML2 code has been given a 3or4 letter prefix to the full name.
Application Prefix Comments
Accommodation ACC
Administration ADM
Access, Stairs & Ladders ASL
Area Based ADP ABA Add-in application
Assembly ASSY
Associations ASSOC None apparent
Common COMM Mixed
Design DES Mixed
Draft DRA Plus ADP, DGN, DXF
Global GLB
Hull Design HULL
Hull Drafting HDRA None
Integrator INT
Application Prefix Comments
Isometric ADP ISO Add-in application
Marine Diagrams DIAG No appware except main form
Monitor MON
Paragon CAT
Review Interface REVI None - Single file
Spooler SPL
Vantage Marine VMAR No appware except start-up Icons are named without regard to any rules, except on odd occasions.
Application Prefix Comments
Design DES Various
Profile PRFL Various
Schematic Model Viewer SMV Various
3. PML expressions
3.1. PML 1 expressions• Text values
VAR !CEname NAME takes the current element’s (ce) name attribute as string
VAR !BRhbore HBORE takes bran bore on hbore, even if its number variable is string VAR !X ‘NAME’ or VAR !X |NAME| sets the variable to the text string ‘NAME’
Note: Quotes ‘ ‘ or vertical bars | | may be used as text delimiters.
• Number values VAR !x (32) VAR !y (52)
Expression VAR !z (!x + !y) results as STRING 84 !!! Expression VAR !z (‘!x’ + ‘!y’) results as STRING !x!y !!! Expression VAR !z (‘$!x’ + ‘$!y’) results as STRING 3252 !!!
VAR !temp (23 * 1.8 + 32) calculate a value and result is STRING 73.4 !!!
Note: VAR always obtain STRING (text) value even if expression calculate numbers!!!
• Boolean values VAR !x TRUE
Note: This expression set variable!x as true. But this is string text. This is not as PML2 Boolean where condition is TRUE or FALSE or 0 or 1. Booleans could be used as parameter in IF statement but from VAR evaluate STRING!!!
• ARRAY (array is variable with many values in rows) VAR !ARRAY[1] 'AVEVA' VAR !ARRAY[10] NAME
Note: VAR always obtain STRING (text) value even if collecting DB elements. The result is string value.
3.2. PML 2 expressions
• STRING
!Name = ‘Fred’ create STRING variable
• REAL
!!Answer = 42 create REAL variable:
Expression !z = !x + !y where !x=32 !y=52 results as REAL 84 !!!
• BOOLEAN
!!Flag = TRUE create BOOLEAN variable. If false than is Boolean 0.
• ARRAY
!newarray = ARRAY() create an empty ARRAY
3.3. Creating Unset and undefined variable
Each new data type supports a String() method that returns a string representing the value of the variable. For example:
!X = 2.5 $* defines a variable X of type REAL with 2.5 as its numeric value !S = !X.String() $* will be a variable of type STRING, with the value “2.5”
!X = REAL()! $* yields the string ’(the empty string) !S = !X.String()
!X = BOOLEAN() $* yields the string ‘’ (the empty string) !S = !X.String()
!X = STRING() $* yields the string ‘Unset’ !S = !X.String()
!X = ARRAY() $* yields the string ‘ARRAY !S = !X.String()
Other variable types are system-defined variables. Most of these have adopted the unset string ‘Unset’. User-defined data types can also provide a String() method. These also support an UNSET representation, and usually adopt the UNSET representation ‘Unset’. For example:
!X = DIRECTION() $* yields the string ‘Unset’ !S = !X.String()
All data types can have the value UNSET which indicates that a variable does not have a value. A variable created without giving it an initial value in fact has the value UNSET:
!!Answer = REAL() !Name = STRING() !Grid = BOOLEAN() !Lengths = ARRAY()
Variables with an UNSET value can be passed around and assigned, but use of an UNSET value where a valid item of data is required will always result in a PML error. The presence of an UNSET value may be tested either with functions or methods:
if ( Unset(!X) ) then if ( !X.Unset() ) then if ( Set(!X) ) then if ( !X.Set() ) then
An UNDEFINED variable is one that does not exist. The existence of a variable may be tested with these functions:
if ( Undefined(!!Y) ) then if ( Defined(!!Y) ) then
There is no equivalent method call. If the variable does not exist, attempting to call a method would result in an error.
3.4. Deleting PML Variables
A variable that exists can be explicitly made UNDEFINED with the Delete() method : !!Y.Delete() Warning: You must not attempt to delete members of objects or forms. 3.5. Mixing of the variables types
Mixing PML1 and PML2 expressions could cause mixing the variables types. Mixing the variables types give error for example: „Cannot assign variable to result - incompatible types (REAL=STRING)”. With VAR you will always obtain a STRING. You could have defined variable type before you assign any value to the variable:
!x = 64 this returns a REAL
VAR !y (64) this returns a STRING
IF (!x eq !y)THEN is invalid syntax because the comparison is mixing variable types. In this case is necessary to put a dollar in front of mixed variable, this forces STRING value IF (!x eq $!y) THEN valid because the dollar in front of !y forces it to be a value not text.
Setting variables using PML2 method is more readable when compared to PML1. PML 2 expressions may be of any complexity, they may contain calls to PML Functions and Methods and include Form gadget values ,object members and methods. $ and quotes are not necessary when using the value of a variable in a PML2 expression. Calculations in expressions can be done in PML1 or PML2 style as follows:
• PML1
VAR !X (64) VAR !Y (32) VAR !Z (|$!X| + |$!Y|)
• PML2
!X = 64 !Y = 32 !Z = !X + !Y
In the PML1 example, !Z is set as a STRING variable as well as !X and !Y are STRING. In the PML2 example, !Z is returned as a REAL, if !X and !Y are REAL. You cannot convert string variable to real if is defined as string type. You need to create another variable and convert text to number into this variable or you need to delete and then reset variable as new variable type. See follow examples:
VAR !BRhbore HBORE takes hbore of bran in variable !BRhbore, but the result will be text string not number. In PDMS up to v.12 the result will looks as (100) and from PDMS v12.1 will looks as (100mm). With text string you cannot use mathematic formulas (+,-,/,*…). It’s necessary to convert this string to real. Syntax will looks like :
VAR !BRhbore REPLACE ('$!BRHBORE', 'mm', ' ') …. take 100mm and removes mm Q VAR !BRhbore check variable type, variable is text string with value 100
!NR = !BRhbore.Real() convert text string 100 to number 100
q VAR !NR check variable type, 100 is real (number) now.
VAR !SUM ($!NR + 50) now it is possible to add +50 to value 100. The result of variable !SUM will looks as 150 but the RESULT is STRING. 150 is now text value !!! Another expression is VAR !VALUE ($!BRhbore) the RESULT is STRING.
!x = REAL() !y = REAL() this is PML2 form to create 2 REAL variables
VAR !x (32) var !y (52) now you have mixed PML1 to assign values, you will obtain error : “(41,357) Value being assigned or variable being assigned to is not of type STRING” ! In this case is necessary to delete variables and create them again with new types as string. !x.delete() !y.delete() AND create again as new type !x=STRING() !y= STRING()
3.6. Expression operators
There are a number of expression operators which are available for use. The actual syntax will depend on whether a PML1 or PML2 style has been adopted. Operators are evaluated in the order of the following list: the ones at the top of the list are evaluated first.
• Brackets () are used to control the order in which operators are evaluated (!A+!B)*2
• Numeric operators: + - / *
• Comparison operators: EQ NE LE GE LT GT
• Logic operators: AND NOT OR
• Numeric functions: SIN COS TAN SQR POW NEGATE ASIN ACOS ATAN LOG ALOG ABS INT NINT
!s = 30 * sin(45)
!t = pow(20,2) (raise 20 to the power 2 (=400)) !f = (match (name of owner, |LPX|) GT 0) 3.7. Boolean Operators
The Boolean, sometimes called Logical, operators have the following meanings:
• EQ TRUE if two expressions have the same value.
• NE TRUE if two expressions have different values.
• LT TRUE if the first expression is less than the second.
• GT TRUE if the first expression is greater than the second.
• LE OR LEQ TRUE if the first expression is less than or equal to the second.
• GE OR GEQ TRUE if the first expression is greater than or equal to the second.
• NOT TRUE if the expression is FALSE.
• AND TRUE if both expressions are TRUE
• OR TRUE if either or both expressions are TRUE.
Note: The operators EQ, NE, LT, GT, LE and GE are sometimes referred to as comparator or relational operators; NOT, AND, and OR are sometimes referred to as Boolean operators. Refer to Precisions of Comparisons for tolerances in comparing numbers.
Several different types of expressions examples: Logical expressions - PDMS attributes
Logical constants
TRUE, ON, YES for true / FALSE, OFF, NO for false Logical Operators
Comparator operators (EQ, NEQ, LT, GT, LEQ, GEQ) Boolean operators (NOT, AND, OR)
Logical functions
BADREF, DEFINED, UNDEFINED, CREATE, DELETED, EMPTY, MATCHWILD, MODIFIED, UNSET, VLOGICAL….
Logical array expressions
PDMS attributes e.g. XLEN YLEN POHE POSITION ORIENTATION Numeric operator -- + Add, - Subtract, * Multiply, / Divide
Numeric function
ABS, ACOS, ASIN, ATAN, SIN, COS, TAN, MATCH, MAX, SQRT.. Real expressions - See numeric functions
Text expressions - A text string, PDMS attributes, Text operators, Text functions 3.8. Concatenation Operator
Values to be concatenated are automatically converted to STRING by the ‘&’ operator. Type the following onto the command line:
!a = 64 !b = 32 !m = ‘mm’ !c = !a & !b & !m
q var !c
Compare this against the results of typing !d = !a + !b
3.9. Communicating with AVEVA Products in PML
All commands need to be supplied to the command processor as STRINGS. This is important when working with element creation (using the NEW syntax) to expand the contents of a PML variable into a string - put a $ in front of it!
!CompType = |ELBO| !dist = 5600 NEW $!CompType
DIST $!dist
3.10. Parameterized Macros
Macros can be parameterized. This means instead of hard coding the values through the macro, the values can be referenced, allowing them to be varied. Simplemac.mac can be parameterized as follows:
NEW EQUIP /$1 NEW BOX
XLEN $2 YLEN $3 ZLEN $4 NEW CYL DIA $3 HEI $4 CONN P1 TO P2 OF PREV
If no parameters are specified, the macro will fail. To avoid this, default values can be put inside the macro. This is done by specified $d1= at the top of the macro. For example: $d1=ABCDEF $d2=300 $d3=400 $d4=600
3.11. Synonyms
Synonyms are abbreviations of longer commands. They are created by assigning the command to a synonym variable:
e.g. $SNewBox=NEW BOX XLEN 100 YLEN 200 ZLEN 300
e.g. $SNewBox=NEW BOX XLEN $S1 YLEN $S2 ZLEN $S3 (A parameterized synonym) To call the first version, type NewBox. For the second version, type NewBox 100 200 300
If all synonyms are killed, the synonyms needed to run PDMS will be removed. This means PDMS will no longer work properly and will require restarting. If synonyms are turned off, some PDMS functionality will also be removed. The return this functionality, the synonyms should be turned back on.
To kill a synonym, type $SXXX= & all synonyms $sk To switch synonyms off and on $S- and $S+
Note: If all synonyms are killed, the synonyms needed to run PDMS will be removed. This means PDMS will no longer work properly and will require restarting. If synonyms are turned off, some PDMS functionality will also be removed. The return this functionality, the synonyms should be turned back on.
$S - defines a local synonym $G - defines a global synonym
$U - prevents the deletion of a global synonym which has already been defined Global synonym ($G) works inside pml functions/methods while local ($S) does not.
3.12. Creating Other Types of Variable
You create variables of types that are system-defined or user-defined, using the OBJECT keyword. For example, to create a variable of type FACTORY:
!NewPlant = object FACTORY()
3.13. Using the Member Values of an Object
The way to set individual members of an object is to use the dot notation as follows: !NewPlant = object FACTORY()
!NewPlant.Name = ProcessA
!NewPlant.Workers = 451 !NewPlant.Output = 2001
The dot notation is used in a similar way to access the value of a member of an object: !People = !NewPlant.Workers sets the variable !People to 451.
3.14. PML Functions and Methods
Functions and Methods may optionally have arguments that can be used to return values. Arguments have a data type which is specified in the function or method definition and they are checked when the Function or Method is called. An argument may be one of the built-in types REAL, STRING or BOOLEAN; an ARRAY; a built-in object or a user-defined object or specified as ANY. Functions and methods can optionally return values as their results. Functions that do not return values are known as PML Procedures.
Here is a definition of a PML Function that has two REAL arguments. It also has a REAL return value, as shown by the final is REAL. Inside a function, the arguments are referenced just as if they were local PML Variables. The RETURN keyword is used to specify the variable that stores the return value:
define function !!Area( !Length is REAL, !Width is REAL ) is REAL !Area = !Length * !Width
return !Area endfunction
Note: You cannot switch to a different PDMS module if a PML Function is running. Use EXIT to exit from the function if it has failed to complete.
When a PML Function is called, all the PML Variables passed as arguments must already exist. In addition, arguments used for input must have a value, which could be a constant, when the function is called:
define function !!LengthOfName(!Name is STRING) is REAL !TidyName = !Name.trim()
return !TidyName.Length() endfunction
The function is called to set the value of a variable !Length as follows: !Length = !!LengthOfName( ' FRED ')
Here ' FRED ' is a string constant passed as an argument. We could rewrite this function so that it returns its results by changing its arguments. The output argument, !Length, will be set to the value required when the function is called:
define function !!LengthAndTrim(!Name is STRING, !Length is REAL) !Name = !Name.Trim()
!Length = !Name.Length() endfunction
Arguments used for output must exist prior to the call and one that is also used as an input argument must also have a value:
!Name = ' FRED ' !Length = REAL()
The function is called to set the value of a variable !Length as follows: !!LengthAndTrim(' FRED ', !Length)
When an argument value is changed within a PML Function its value outside the function is also changed. The following call is incorrect, as the function cannot modify a constant: !!LengthAndTrim(' FRED ' ,4 ) $* WRONG
A PML Function returning a value may be used wherever an expression or PML Variable can be used, for example, this call to the !Area function defined above:
!PartLength = 7 !PartWidth = 6
!SurfaceArea = !!Area(!PartLength, !PartWidth) 3.15. Storing and Loading PML Functions
When a PML Function is called it is loaded automatically from its source file in a directory located via the environment variable PMLLIB. The name of the external file must be lowercase and must have the .pmlfnc suffix. The source of a PML Function invoked as !!AREA or !!Area or !!area all correspond to the file named area.pmlfnc.
Note: The !! signifies that the function is user-defined and that it is global - but !! does not form part of the external filename. All user-defined functions are global and only one may be defined per file. The define function must be the first line in the file and that its name and the file name must correspond.
3.16. Arguments of type ANY
You may specify ANY as the type of an argument (and even as the type of the function return value).
Note: The use of ANY should be the exception rather than the rule as it switches off argument type checking - an important feature of PML Functions to help ensure correct functioning of your PML.
In the case an argument of type ANY, a value of any type may be passed as the argument to the function:
define function !!Print(!Argument is ANY) $P $!Argument
endfunction
Where an argument of type ANY is used, you may need to find out its actual type before you can do anything with it. The ObjectType() method can be used for this purpose:
define function !!AnyType(!Argument is ANY) Type = !Argument.pmlobjectType()
if ( !Type EQ 'STRING' ) then - - do something with a STRING elseif ( !Type EQ 'REAL' ) then - - do something with a REAL elseif ( !Type EQ 'DBREF' ) then - - do something with a DB Reference else
- - do something with all other types or give an error endif
endfunction
3.17. PML Procedures
A PML Procedure is a PML Function that does not return a result. A function is defined as a procedure by omitting the data type at the end of the define function statement:
define function !!Area( !Length is REAL, !Width is REAL, !Result is REAL) !Result = !Length * !Width
endfunction
Here we are using an output argument, !Result, to return the result rather than using a function return value. The arguments to the !!Area procedure can be set as follows, and then the procedure invoked with the call command.
!SurfaceArea = REAL() !Partlength = 7
!PartWidth = 6
call !!Area(!PartLength, !PartWidth, !SurfaceArea)
There will be an error if you attempt to assign the result of a PML Procedure because there is no return value to assign. So, for example you can say:
call !!Area(!PartLength, !PartWidth, !SurfaceArea) !Answer = !SurfaceArea
But you cannot say:
!Answer = !!Area(!PartLength, !PartWidth, !SurfaceArea) $* WRONG
The ( ) parentheses after the name of a procedure or function must always be present even for procedures that do not need arguments:
define function !!Initialize() !TotalWeight = 0
!!MaxWeight = 0 endfunction call !!Initialize()
Although the call keyword is strictly speaking optional, its use is recommended with procedures.
Note: As well as procedures, you can invoke a PML Function that has a return value using call, in which case the function result value is discarded.
3.18. Using the Methods of an Object
A method is a function that is specific to an object. The Software Customization Reference Manual contains a table of the object types supplied as part of PML 2. For each object type, there is a list of the associated methods and members. For each object type, the table shows:
Name The name of the method or member. For example, a REAL object has a method named Cosine. If there are any arguments, they are indicated in the brackets () after the name. For example, the REAL object has a method named BETWEEN which takes two REAL arguments.
Result or Type For members, we use the heading Type; for methods, we use the heading Result. The type of the member or the result describes what kind of object we are expecting to see as a member or result of the method. For example, the result of the method Cosine is a REAL value. Some methods do not return a value: these are shown as NO RESULT. Status This column is used to give other information about the method or member. For methods, this column tells you whether the method modifies the state of the object. For members, this column tells you whether the member is Mutable (by the user) or Read Only. Note that for the system-defined PDMS object types, members correspond to PDMS attributes
Purpose This column tells you what the member or method does.
This section explains how to use methods, using a STRING variable as an example. Although the STRING is a simple object type, it has a large number of methods which can be called. For example, if you are interested in the length of the string value, look under the list in the Software Customization Reference Manual for STRING objects, and you will find a method named Length. This method returns a REAL value (the number of characters in the string), but has no effect on the variable itself. You can extract the number of characters in the string and store it in a new variable, !Nchars, by calling the method as follows:
!Nchars = !MyString.length() $* A method call
Notice the dot separator between the name of the variable and the name of the method. Also note the ( ) brackets following the name of the method. The brackets are used to enclose the arguments of the method, but they must be present even if there are no arguments.
3.19. Methods on User-Defined Object Types
When you define a new object type, you can also define methods which can be used to handle all objects created with the new type. PML Method definitions are stored in the same file as the object definition, after the endobject command. Here is an example of an object which defines three methods to illustrate the main ideas. Note that within a method, !This represents the object which invoked the method and !This.Answer is the way to refer to member Answer of this object.
Defines the object, with a single member, Answer. define object LIFE
member .Answer is REAL endobject
Defines a method with no arguments but the same name as the type of the object is called the default constructor method. If the default constructor method is present, PML will call it automatically to initialize the object whenever an object of that type is created.
define method .Life() !This.Answer = 42 Endmethod
A method may return a result in just the same way as a PML Function using the return command. Set a member of the object using !This.membername.
define method .Answer() IS REAL return !This.Answer
endmethod
define method .Answer( !Value Is REAL) !This.Answer = !Value
Endmethod
These methods might be used in the following way: !Marvin = object LIFE()
-- The method .Life() was called automatically !Number = !Marvin.Answer()
-- !Number is set to the value 42 !Marvin.Answer(40)
!Number = !Marvin.Answer() -- !Number now has the value 40
Warning: When you create a new object type, or change an existing definition, you must load the definition by giving the command:
pml reload object _name_ 3.20. Method Overloading
Two or more methods on an object may share the same name providing they have different arguments. This is called method overloading. PML will invoke the method with the arguments which match the method call. It is common practice:
• To use a method with the same name as a member and one argument of the same type to set the member’s value. For example:
!Marvin.Answer(65)
• To use a method of the same name as a member returning a value of the same type but with no arguments to get the member’s value. For example:
!Number = !Marvin.Answer()
3.21. Constructor Methods with Arguments
When an object is created, it is possible to supply arguments that are passed by PML to a constructor method with matching arguments instead of the default constructor method: !Marvin = object LIFE(40)
This would invoke a method: define method .Life(!Value IS REAL)
3.22. Overloading with ANY
As with PML Functions, the type of a method argument may be specified as ANY. If method overloading is being used, PML will invoke the method with a matching set of explicitly typed arguments in preference to calling a method with arguments of type ANY, irrespective of the order the methods appeared in the object definition file:
define method .SetValue( !Argument Is ANY) define method .SetValue( !Argument Is REAL)
Then: !SomeObject.SetValue(100) will invoke the method with the REAL argument, but !SomeObject.SetValue(‘Priceless’ ) will invoke the method with the ANY argument.
3.23. Invoking a Method from Another Method
Within a method !This.Methodname() refers to another method on the same object. So our second LIFE constructor method, the one with an argument, could be defined as:
define method .Life(!Value IS REAL) !This.Answer(!Value)
endmethod
3.24. Developing a PML Object with Methods
Whenever you add a new method to an object, you need to tell PML to re-read the object definition, by giving the command:
pml reload object life
It is not necessary to use this command if you are simply editing an existing method (although you will have to use it if you edit a form definition file, and change the default constructor method, described in Form Definition File.)
3.25. Forms as Global Variables
In PML 2, forms are a type of global variable. This means that a form cannot have the same name as any other global variable or any other form. Note that a form definition is also the definition of an object, so a form cannot have the same name as any other object type.
4. ARRAYs in PML
An ARRAY variable can contain many values, each of which is called an array element. An Array is created automatically by creating one of its array elements.
!Array = Array()
This is an empty variable but it has been defined as an array. Adding elements to the array: Type 1
!Array[1] = ‘BOB’ !Array[2] = 45 !Array[10] = !!CE Type 2
!Array.Append(‘BOB’) !Array.Append(45) !Array.Append(!!CE)
Type 1 adds string values into exact position of array element (1,2 and 10). Type2 add string values to the end of lists (11,12,13). To check array list query :
q var !Array <ARRAY> [1] <STRING> 'BOB' [2] <REAL> 45 [10] <DBREF> 'KELLY' [11] <STRING> 'BOB' [12] <REAL> 'GEORGE' [13] <DBREF> 'KELLY'
To check exact array member query: q var !Array[1]
<STRING> 'BOB'
Note: How array elements are referred to by means of a subscript expression in [ ] square brackets and that there must be no space between the end of the array name and the subscript. Array elements are accessed in the same way when using the value in an expression:
!Average = ( !Sample[1] + !Sample[2] + !Sample[3] ) / 3 )
The individual elements of an array variable can be set independently and in any order. Thus you can set !X[1] and !X[10] without setting any of the intervening elements !X[2] to !X[9]. In other words PML arrays are allowed to be ‘sparse’ and to have gaps between the subscript numbers which have values set. Negative subscripts are no longer permitted. An array subscript of zero is allowed but you are advised against using it as many of the array facilities ignore array element zero. An array subscript may be an expression of any complexity provided it evaluates to a positive REAL result and may even include a call to a PML Function:
!Value = !MyArray[!A + (!B * !!MyFunction() ) + !C ]
PML Arrays may be heterogeneous. That is to say the elements of a PML array do not have to be all of the same type. Array elements may even be user-defined objects. Values to be concatenated are automatically converted to STRING by the ‘&’ operator. Type the following onto the command line: Non-existent array elements - after the last set element of the array and the non-existent elements in the gaps of a sparse array - are all UNDEFINED: the function Undefined() will return TRUE and the function Defined() will return FALSE for all these subscripts.