Skip to main content

This is documentation for Caché & Ensemble. See the InterSystems IRIS version of this content.

For information on migrating to InterSystems IRIS, see Why Migrate to InterSystems IRIS?

OREF Basics

OREF Basics

When you create an object, the system creates an in-memory structure, which holds information about that object, and also creates an OREF (object reference), which is a pointer to that structure.

The object classes provide several methods that create OREFs. When you work with any of the object classes, you use OREFs extensively. You use them when you specify values of properties of an object, access values of properties of the object, and call instance methods of the object. Consider the following example:

SAMPLES>set person=##class(Sample.Person).%New()
 
SAMPLES>set person.Name="Carter,Jacob N."
 
SAMPLES>do person.PrintPerson()
 
Name: Carter,Jacob N.

In the first step, we call the %New() method of the Sample.Person class, which creates an object and returns an OREF that points to that object. We set the variable person equal to this OREF. In the next step, we set the Name property of object. In the third step, we invoke the PrintPerson() instance method of the object. (Note that the Name property and the PrintPerson() method are both just examples—these are defined in the Sample.Person class but are not part of the general object interface.)

An OREF is transient; the value exists only while the object is in memory and is not guaranteed to be constant over different invocations.

Caution:

An OREF is only valid within the namespace where it was created; hence, if there are existing OREFs and the current namespace changes, any OREF from the previous namespace is no longer valid. If you attempt to use OREFs from other namespaces, there might not be an immediate error, but the results cannot be considered valid or usable, and may cause disastrous results in the current namespace.

INVALID OREF Error

In simple expressions, if you try to set a property, access a property, or invoke an instance method of a variable that is not an OREF, you receive an <INVALID OREF> error. For example:

SAMPLES>write p2.PrintPerson()
 
WRITE p2.PrintPerson()
^
<INVALID OREF>
SAMPLES>set p2.Name="Dixby,Jase"
 
SET p2.Name="Dixby,Jase"
^
<INVALID OREF>
Note:

The details are different when the expression has a chain of OREFs; see “Introduction to Dot Syntax.”

Testing an OREF

Caché provides a function, $ISOBJECT, which you can use to test whether a given variable holds an OREF. This function returns 1 if the variable contains an OREF and returns 0 otherwise. If there is an chance that a given variable might not contain an OREF, it is good practice to use this function before trying to set a property, access a property, or invoke an instance method of the variable.

OREFs, Scope, and Memory

Any given OREF is a pointer to an in-memory object to which other OREFs might also point. That is, the OREF (which is a variable) is distinct from the in-memory object (although, in practice, the terms OREF and object are often used interchangeably).

Caché manages the in-memory structure automatically as follows. For each in-memory object, Caché maintains a reference count — the number of references to that object. Whenever you set a variable or object property to refer to a object, its reference count is automatically incremented. When a variable stops referring to an object (if it goes out of scope, is killed, or is set to a new value), the reference count for that object is decremented. When this count goes to 0, the object is automatically destroyed (removed from memory) and its %OnClose() method (if present) is called.

For example, consider the following method:

Method Test()
{
    Set person = ##class(Sample.Person).%OpenId(1)

    Set person = ##class(Sample.Person).%OpenId(2)
}

This method creates an instance of Sample.Person and places a reference to it into the variable person. Then it creates another instance of Sample.Person and replaces the value of person with a reference to it. At this point, the first object is no longer referred to and is destroyed. At the end of the method, person goes out of scope and the second object is destroyed.

Removing an OREF

If needed, to remove an OREF, use the KILL command:

 kill OREF

Where OREF is a variable that contains an OREF. This command removes the variable. If there are no further references to the object, this command also removes the object from memory, as discussed earlier.

OREFs, the SET Command, and System Functions

For some system functions (for example, $Piece, $Extract, and $List), Caché supports an alternative syntax that you can use to modify an existing value. This syntax combines the function with the SET command as follows:

 SET function_expression = value

Where function_expression is a call to the system function, with arguments, and value is a value. For example, the following statement sets the first part of the colorlist string equal to "Magenta":

 SET $PIECE(colorlist,",",1)="Magenta"

It is not supported to modify OREFs or their properties in this way.

Feedback