Object-Specific ObjectScript Features
This page summarize the ObjectScript features that are specific to working with classes and objects.
Relative Dot Syntax (..)
The relative dot syntax (..) provides a mechanism for referencing a method or property in the current context. The context for an instance method or a property is the current instance; the context for a class method is the class in which the method is implemented. You cannot use relative dot syntax in a class method to reference properties or instance methods, because these require the instance context.
For example, suppose there is a Bricks property of type %Integer:
Property Bricks As %Integer;
A CountBricks() method can then refer to Bricks with relative dot syntax:
Method CountBricks()
{
Write "There are ",..Bricks," bricks.",!
}
Similarly, a WallCheck() method can refer to CountBricks() and Bricks:
Method WallCheck()
{
Do ..CountBricks()
If ..Bricks < 100 {
Write "Your wall will be small."
}
}
##class Syntax
The ##class syntax allows you to:
-
Invoke a class method when there is no existing or open instance of a class.
-
Cast a method from one class as a method from another.
##class is not case-sensitive.
Invoking a Class Method
To invoke a class method, the syntax is either of the following:
>Do ##class(Package.Class).Method(Args) >Set localname = ##class(Package.Class).Method(Args)
It is also valid to use ##class as part of an expression, as in
Write ##class(Class).Method(args)*2
without setting a variable equal to the return value.
A frequent use of this syntax is in the creation of new instances:
>Set LocalInstance = ##class(Package.Class).%New()
Casting a Method
To cast a method of one class as a method of another class, the syntax is either of the following:
>Do ##class(Package.Class1)Class2Instance.Method(Args) >Set localname = ##class(Package.Class1)Class2Instance.Method(Args)
You can cast both class methods and instance methods.
For example, suppose that two classes, MyClass.Up and MyClass.Down, both have Go() methods. For MyClass.Up, this method is as follows
Method Go()
{
Write "Go up.",!
}
For MyClass.Down, the Go() method is as follows:
Method Go()
{
Write "Go down.",!
}
You can then create an instance of MyClass.Up and use it to invoke the MyClass.Down.Go method:
>Set LocalInstance = ##class(MyClass.Up).%New() >Do ##class(MyClass.Down)LocalInstance.Go() Go down.
It is also valid to use ##class as part of an expression, as in
Write ##class(Class).Method(args)*2
without setting a variable equal to the return value.
A more generic way to refer to other methods are the $METHOD and $CLASSMETHOD functions, which are for instance and class methods, respectively; these are described in Dynamically Accessing Objects. These provide a mechanism for referring to packages, classes, and methods programmatically.
Accessing a Class Parameter
To access a class parameter, you can use the following expression:
##class(Package.Class).#PARMNAME
Where Package.Class is the name of the class and PARMNAME is the name of the parameter. For example:
w ##class(%XML.Adaptor).#XMLENABLED
displays whether methods generated by the XML adaptor are XML enabledOpens in a new tab, which by default is set to 1.
You can also use the $PARAMETER functions, which is described in Dynamically Accessing Objects.
$this Syntax
The $this variable provides a handle to the OREF of the current instance, such as for passing it to another class or for another class to refer to the properties or methods of the current instance. When an instance refers to its own properties or methods, relative dot syntax is faster and thus is preferred.
$this is not case-sensitive; hence, $this, $This, $THIS, or any other variant all have the same value.
For example, suppose there is an application with an Accounting.Order class and an Accounting.Utils class. The Accounting.Order.CalcTax() method calls the Accounting.Utils.GetTaxRate() and Accounting.Utils.GetTaxableSubtotal() methods, passing the city and state values of the current instance to the GetTaxRate() method and passing the list of items ordered and relevant tax-related information to GetTaxableSubtotal(). CalcTax() then uses the values returned to calculate the sales tax for the order. Hence, its code is something like:
Method CalcTax() As %Numeric
{
Set TaxRate = ##class(Accounting.Utils).GetTaxRate($this)
Write "The tax rate for ",..City,", ",..State," is ",TaxRate*100,"%",!
Set TaxableSubtotal = ##class(Accounting.Utils).GetTaxableSubTotal($this)
Write "The taxable subtotal for this order is $",TaxableSubtotal,!
Set Tax = TaxableSubtotal * TaxRate
Write "The tax for this order is $",Tax,!
}
The first line of the method uses the ##Class syntax (described above) to invoke the other method of the class; it passes the current object to that method using the $this syntax. The second line of the method uses relative dot syntax to get the values of the City and State properties. The action on the third line is similar to that on the first line.
In the Accounting.Utils class, the GetTaxRate() method can then use the handle to the passed-in instance to get handles to various properties — for both getting and setting their values:
ClassMethod GetTaxRate(OrderBeingProcessed As Accounting.Order) As %Numeric
{
Set LocalCity = OrderBeingProcessed.City
Set LocalState = OrderBeingProcessed.State
// code to determine tax rate based on location and set
// the value of OrderBeingProcessed.TaxRate accordingly
Quit OrderBeingProcessed.TaxRate
}
The GetTaxableSubtotal() method also uses the handle to the instance to look at its properties and set the value of its TaxableSubtotal property.
Hence, the output at the Terminal from invoking the CalcTax() method for MyOrder instance of the Accounting.Order class would be something like:
>Do MyOrder.CalcTax() The tax rate for Cambridge, MA is 5% The taxable subtotal for this order is $79.82 The tax for this order is $3.99
##super Syntax
Suppose that a subclass method overrides a superclass method. From within the subclass method, you can use the ##super() syntax to invoke the overridden superclass method.
##super is not case-sensitive.
For example, suppose that the class MyClass.Down extends MyClass.Up and overrides the Simple class method. If the code for MyClass.Up.Simple() is:
ClassMethod Simple()
{
Write "Superclass.",!
}
and the code for MyClass.Down.Simple() is:
ClassMethod Simple()
{
Write "Subclass.",!
Do ##super()
}
then the output for subclass method, MyClass.Down.Simple(), is:
>Do ##Class(MyClass.Down).Simple() Subclass. Superclass. >
A more generic way to refer to other methods are the $METHOD and $CLASSMETHOD functions, which are for instance and class methods, respectively; these are described in Dynamically Accessing Objects. These provide a mechanism for referring to packages, classes, and methods programmatically.
Calls That ##super Affects
##super only affects the current method call. If that method makes any other calls, those calls are relative to the current object or class, not the superclass. For example, suppose that MyClass.Up has MyName() and CallMyName() methods:
Class MyClass.Up Extends %Persistent
{
ClassMethod CallMyName()
{
Do ..MyName()
}
ClassMethod MyName()
{
Write "Called from MyClass.Up",!
}
}
and that MyClass.Down overrides those methods as follows:
Class MyClass.Down Extends MyClass.Up
{
ClassMethod CallMyName()
{
Do ##super()
}
ClassMethod MyName()
{
Write "Called from MyClass.Down",!
}
}
then invoking the CallMyName() methods have the following results:
USER>d ##class(MyClass.Up).CallMyName()
Called from MyClass.Up
USER>d ##class(MyClass.Down).CallMyName()
Called from MyClass.Down
MyClass.Down.CallMyName() has different output from MyClass.Up.CallMyName() because its CallMyName() method includes ##super and so calls the MyClass.Up.CallMyName() method, which then calls the uncast MyClass.Down.MyName() method.
##super and Method Arguments
##super also works with methods that accept arguments. If the subclass method does not specify a default value for an argument, make sure that the method passes the argument by reference to the superclass.
For example, suppose the code for the method in the superclass (MyClass.Up.SelfAdd()) is:
ClassMethod SelfAdd(Arg As %Integer)
{
Write Arg,!
Write Arg + Arg
}
then its output is:
>Do ##Class(MyClass.Up).SelfAdd(2) 2 4 >
The method in the subclass (MyClass.Down.SelfAdd()) uses ##super and passes the argument by reference:
ClassMethod SelfAdd(Arg1 As %Integer)
{
Do ##super(.Arg1)
Write !
Write Arg1 + Arg1 + Arg1
}
then its output is:
>Do ##Class(MyClass.Down).SelfAdd(2) 2 4 6 >
In MyClass.Down.SelfAdd(), notice the period before the argument name. If we omitted this and we invoked the method without providing an argument, we would receive an <UNDEFINED> error.
$CLASSNAME and Other Dynamic Access Functions
InterSystems IRIS® data platform supplies several functions that support generalized processing of objects. They do this by allowing a reference to a class and one of its methods or properties to be computed at runtime. (This is known as reflection in Java.) These functions are:
-
$CLASSNAME — Returns the name of a class.
-
$CLASSMETHOD — Supports calls to a class method.
-
$METHOD — Supports calls to an instance method.
-
$PARAMETER — Returns the value of a class parameter of the specified class.
-
$PROPERTY — Supports references to a particular property of an instance.
The function names are shown here in all uppercase letters, but they are, in fact, not case-sensitive.
$CLASSNAME
This function returns the name of a class. The signature is:
$CLASSNAME(Instance)
where Instance is an OREF.
For more information, see $CLASSNAME.
$CLASSMETHOD
This function executes a named class method in the designated class. The signature is:
$CLASSMETHOD (Classname, Methodname, Arg1, Arg2, Arg3, ... )
where:
An existing class.
A method of the class specified by the first argument.
A series of expressions to be substituted for the arguments to the designated method.
For more information, see $CLASSMETHOD.
$METHOD
This function executes a named instance method for a specified instance of a designated class. The signature is:
$METHOD (Instance, Methodname, Arg1, Arg2, Arg3, ... )
where:
An OREF of instance of a class.
A method of the class specified by the instance in the first argument.
A series of expressions to be substituted for the arguments to the designated method.
For more information, see $METHOD.
$PARAMETER
This function returns the value of a class parameter of the designated class. The signature is:
$PARAMETER(Instance,Parameter)
where:
An OREF of instance of a class.
Either the fully qualified name of a class or an OREF of an instance of the class.
A parameter of the given class.
For more information, see $PARAMETER.
$PROPERTY
This function gets or sets the value of a property in an instance of the designated class. If the property is multidimensional, the following arguments after the property name are used as indexes in accessing the value of the property. The signature is:
$PROPERTY (Instance, PropertyName, Index1, Index2, Index3... )
where:
An OREF of instance of a class.
A property of the class specified by the instance in the first argument.
For multidimensional properties, indexes into the array represented by the property.
For more information, see $PROPERTY.
i%<PropertyName> Syntax
This section provides some additional information on instance variables. You do not need to refer to these variables unless you override an accessor method for a property; see Using and Overriding Property Methods.
When you create an instance of any class, the system creates an instance variable for each non-calculated property of that class. The instance variable holds the value of the property. For the property PropName, the instance variable is named i%PropName, and this variable name is case-sensitive. These variables are available within any instance method of the class.
For example, if a class has the properties Name and DOB, then the instance variables i%Name and i%DOB are available within any instance method of the class.
Internally, InterSystems IRIS also uses additional instance variables with names such as r%PropName and m%PropName, but these are not supported for direct use.
Instance variables have process-private, in-memory storage allocated for them. Note that these variables are not held in the local variable symbol table and are not affected by the Kill command.
..#<Parameter> Syntax
The ..#<Parameter> syntax allows for references to class parameters from within methods of the same class.
For example, if a class definition include the following parameter and method:
Parameter MyParam = 22;
and the following method:
ClassMethod WriteMyParam()
{
Write ..#MyParam
}
Then the WriteMyParam() method invokes the Write command with the value of the MyParam parameter as its argument.