• No results found

PDMS PML Manual - 1

N/A
N/A
Protected

Academic year: 2021

Share "PDMS PML Manual - 1"

Copied!
100
0
0

Loading.... (view fulltext now)

Full text

(1)

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.

(2)

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

(3)

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

(4)

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

(5)

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

(6)

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

(7)

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

(8)

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

(9)

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.

(10)

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.

(11)

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’).

(12)

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

(13)

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.

(14)

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

(15)

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.

(16)

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

(17)

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

(18)

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:

(19)

!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

(20)

!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

(21)

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.

(22)

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:

(23)

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:

(24)

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.

(25)

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.

(26)

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)

(27)

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.

(28)

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.

References

Related documents