When viewing this book online, use the preface of this book to quickly find related topics.

Introduction to Property Methods

Properties have a number of methods associated with them automatically. These methods are not inherited via standard inheritance. Rather, they use a special property behavior mechanism to generate a series of methods for each property.

Each property inherits a set of methods from two places:

The %Property class, which provides certain built-in behavior, such as Get(), Set(), and validation code.

The data type class used by the property, if applicable. Many of these methods are method generators.

Property Behavior

The property behavior classes are system classes. You cannot specify or modify property behavior.

The compiled Person class has a set of methods automatically generated for each of its properties. These methods are inherited from the system Property class as well as the data type class associated with the property. The names of these generated methods are the property name concatenated with the name of the method from the inherited class. For example, some of the methods associated with the DOB property are:

The InterSystems IRIS dot syntax for referring to object properties is an interface for a set of accessor methods to retrieve and set values. For each non-calculated property, whenever the code refers to oref.Prop (where oref is an object and Prop is a property), it is executed as if a system-supplied PropGet() or PropSet() method were invoked. For example:

Setperson.DOB=x

acts as if the following method was called:

Doperson.DOBSet(x)

while:

Writeperson.Name

acts like:

Writeperson.NameGet()

In most cases, you cannot see the actual PropGet() and PropSet() methods; access for simple properties is implemented directly within the InterSystems IRIS virtual machine for optimal performance. You can, however, provide PropGet() and PropSet() methods for a specific property, as long as that property is not object-typed or multidimensional. If you define these methods, the system automatically invokes them at runtime. The following sections describe how to define these accessor methods. Within the custom methods, you can perform any special processing that your application requires.

Note that the last screen of the New Property Wizard in Studio provides options for creating a custom Get() method, Set(), or both. If you use these options, Studio defines stub methods with suitable signatures.

Property Accessors for Object-Valued Properties

For every reference property there are SetObject() (using OID value) and SetObjectId() (using ID value) methods. For example, to assign a particular saved Person object as the owner of a Car object, use the following code:

To refer to the value of this property, this method must use the variable i%PropertyName. This name is case-sensitive.

Important:

Within this getter method for a given property, do not use ..PropertyName syntax to refer to the value of that property. If you attempt to do so, the result is a <FRAMESTACK> error, caused by a recursive series of references. You can, however, use ..PropertyName to refer to other properties, because doing so does not cause any recursion.

Note that it is not supported to override accessor methods for object-typed properties or for multidimensional properties. Also because the maximum length of a method name is 220 characters, it is not possible to create accessor methods for properties that are 218, 219, or 220 characters long.

The following shows an example, a setter method for a property named HasValue, which is of type %Boolean:

To set the value of this property, this method must set the variable i%PropertyName. This name is case-sensitive.

Important:

Within this setter method for a given property, do not use ..PropertyName syntax to refer to the value of that property. If you attempt to do so, the result is a <FRAMESTACK> error, caused by a recursive series of references. You can, however, use ..PropertyName to refer to other properties, because doing so does not cause any recursion.

Note that it is not supported to override accessor methods for object-typed properties or for multidimensional properties. Also because the maximum length of a method name is 220 characters, it is not possible to create accessor methods for properties that are 218, 219, or 220 characters long.

For example, suppose that MyProp is of type %String. We could define the following setter method:

Notice that this example refers to the Namespaces property of the same object by using the ..PropertyName syntax. This usage is not an error, because it does not cause any recursion.

Defining an Object-Valued Property with a Custom Accessor Method

As noted earlier, it is not supported to override accessor methods for object-typed properties. If you need to define a property that holds object values and you need to define custom accessor methods, define the property with the type %CacheString. This is not an object class but is rather a generic class, and it is permitted to override the accessor methods for this property. When using the property, set it equal to an instance of the desired class.

For example, the following class includes the property Zip, whose formal type is %CacheString. The property description indicates that the property is meant to be an instance of Sample.USZipCode. The class also defines the ZipGet() and ZipSet() property methods.

ClassPropMethods.DemoExtends%Persistent{///Timestamp for viewing ZipPropertyLastTimeZipViewedAs%TimeStamp;///Timestamp for changing ZipPropertyLastTimeZipChangedAs%TimeStamp;///When setting this property, set it equal to instance of Sample.USZipCode.///The type is %CacheString rather than Sample.USZipCode, so that it's possible ///to override ZipGet() and ZipSet().PropertyZipAs%CacheString;MethodZipGet()As%CacheString[ServerOnly=1 ]{// get id, swizzle referenced objectsetid=i%Zipif(id'=""){setzip=##class(Sample.USZipCode).%OpenId(id)set..LastTimeZipViewed=$zdt($zts)}else{setzip=""}returnzip}MethodZipSet(zipAs%CacheString)As%Status[ServerOnly=1 ]{// set i% for new zipif($isobject(zip)&&zip.%IsA("Sample.USZipCode")){setid=zip.%Id()seti%Zip=idset..LastTimeZipChanged=$zdt($zts)}else{seti%Zip=""}quit$$$OK}}