====== Namespaces ====== Keyword **namespace** is used to declare new namespaces. Namespace is a collection of functions, classes, variables, etc. aggregated in single unit. Namespaces can contain other (inner) namespaces too. "Under the hood" namespace is just a named global object. Keyword //super// can be used to access members of parent namespace that have the same name as in inner namespace. Declaration of namespace: namespace { [ | | | | ]* } ====== Classes ====== Keyword **class** is used to define new classes (types of objects): class [ : ] { [ | | | | ]* } Where: * '''' is a standard function declaration. Such function can be used as an instance method or static method of the class. * '''' is a function with predefined name //this//. * '''' is a special type of member function. See more details below. * '''' is a standard var declaration - allows to define class or module variables (a.k.a. static variables) * '''' is a declaration of named constant. * '''' is a declaration of inner type. ===== Constructors ===== Function with the name //this// being declared in context of some type will serve a role of constructor for all instances of the class. class Tor { function this() { this.one = 1; } } Main goal of the constructor is to initialize instance of the class (a.k.a. object of the class) - create and initialize all fields the instance shall contain. Object that is being created is accessible through variable named //this// inside the constructor ((Idea of the name //this// for a constructor was borrowed from the [[http://digitalmars.com/d/class.html#constructors|D language]])). Compiler generates invocation of the constructor when it handles new operator: var tor = new Tor(); // tor.one == 1 at this point In any other aspect ''function this()'' is an ordinary function that may have any number of parameters defined including [[tiscript:functions#optional_parameters|Optional parameters]]. ===== Methods ===== Function with any other name being declared in context of some type is known as a method of the class. If some method-function has a reference to the //this// variable then it is said that this function is an //instance method//. If the function does not refer to the //this// variable then it is a //class method// (a.k.a. //static method//). ==== Instance Methods ==== Instance methods must be called in context of some object of the class: type Tor { function rotate( angle ) { this.angle = angle; this.update(); } } var tor = new Tor(); tor.rotate(270); // calling method Tor.rotate in context of // 'tor' instance. ==== Static Methods ==== Static method of some type a) does not refer to the //this// variable and/thus b) can be called by using //Type.Method// notation type Tor { var all = []; function rotateAll( angle ) { for(var t in Tor.all) t.rotate(angle); } } Tor.rotateAll(270); // calling method Tor.rotateAll as a class method. ===== Properties ===== TIScript supports definition of computable properties - special functions that will be executed to set or get value of property. Syntax of computable property definition: property ( ) { [ | get | set ]+ } Body of the property can contain statements that can appear in normal function body as also special //get// and //set// sections. //get// section(s) will be executed conditionally when the function will be invoked for getting value of the property and //set// section for setting value of the property. Samples: type Baz { function this() { this._first = 1; this._second = 2; } property first( val ) { get return this._first; // single expression get block set this._first = val; // single expression set block } property second( val ) { stdout << "second"; get { stdout << "get\n"; return this._second + 2; } set { stdout << "set\n"; this._second = val - 2; } } } Note that the property function declaration must have single parameter defined, e.g. ''val''. ==== Virtual Properties ==== It is possible to define so called Undefined Property Handler that allows to deal with undefined properties. Syntax of Undefined Property Handler is similar to the computable property handler but with 'undefined' used as its name: property undefined ( name, value ) { [ | get | set ]+ } Undefined Property Handler function has to have precisely two parameters: name of the property and its value that used in property set operation. Undefined Property Handlers can be used in cases when set of properties is unknown upfront - in other words to support Virtual Properties. For example you may wish to access fields of recordset as properties property Recordset.undefined(name,val) { get return this.getFieldValue(name); } ... var rs = DB.exec("SELECT firstName, secondName FROM employee"); var n1 = rs.firstName; // redirect to rs.getFieldValue(#firstName); call var n2 = rs.secondName; // through property undefined() ===== Type variables ===== Type variables (class static or namespace variables) are variables that are defined in context of some type using //var// keyword. Example: namespace Toz { var all = []; // create variable that contains empty array; var singleton = { something: 123; }; // create variable that contains object; var counter = 0; // create variable that contains integer zero; } To access such variables use their fully qualified names: Toz.all.push("anything"); Toz.counter += 1; ===== Constants ===== Namespace constants (a.k.a. constants) are read-only variables that defined in context of some type using ''const'' keyword. Example: namespace Toz { const ALIGN_LEFT = 1; const ALIGN_CENTER = 2; const ALIGN_RIGHT = 3; } To access such constants use their fully qualified names: switch(alignment) { case Toz.ALIGN_LEFT: ... break; case Toz.ALIGN_CENTER: ... break; case Toz.ALIGN_RIGHT: ... break; default: ... break; }