Methods are operations that are associated with and can be invoked upon
an object. Methods are executed within a Caché process; when you are
using Caché object on a client (such as a Java program), Caché
automatically invokes methods within the appropriate server process.
Every method has a name, a formal argument specification, and an implementation
(code). A method name must be unique within its class.
Note:
The word
method generally refers to instance methods,
or methods that act on a specific instance of a class. Caché also supports
class methods (methods that do not act on a specific instance).
Methods operate on variables that they receive through their arguments.
A method can take any number of arguments. A method's definition specifies
the arguments that it takes and each argument's data type. You can also specify
the default value for any missing argument.
Additionally, a method definition specifies which arguments are called
by reference and which are called by value. The default is to call an argument
by value. (Note that an argument that is an object in the form of an OREF
is always passed by reference, regardless of what the method definition specifies.)
For instance, here is a
Calculate method taking
three arguments:
Method Calculate(count As %Integer, name, state As %String = "CA")
{
// ...
}
Specifying Default Values
To specify an argument's default value, set it equal to the desired
value:
Method Test(flag As %Integer = 0)
{
}
When a method is invoked, it uses its default values (if specified)
for any missing arguments.
By default, method arguments are passed by value. You can call an argument
by reference using the ByRef modifier:
/// Swap value of two integers
Method Swap(ByRef x As %Integer, ByRef y As %Integer)
{
Set temp = x
Set x = y
Set y = temp
}
You can also specify an argument whose value is returned by reference
but has no incoming value by using the Output modifier. This is equivalent
to ByRef except that any incoming argument values are ignored.
Method CreateObject(Output newobj As MyApp.MyClass) As %Status
{
Set newobj = ##class(MyApp.MyClass).%New()
Quit $$$OK
}
In Caché ObjectScript, when calling a method which has arguments
that are passed by reference (ByRef or Output), you must place a dot
. before
each of the arguments being called by reference, such as:
Do obj.Swap(.arg1, .arg2)
Each method's definition specifies whether it returns a value and, if
so, the return value's type. The return type of a method is a class. If the
return type is a data type class, then the method returns a literal value
(such as a number or string). Otherwise, the method returns a reference (OREF)
to an instance of a class.
The syntax for specifying a return type is:
Method MethodName() As ReturnType
{
}
Method Add(x As %Integer, y As %Integer) As %Integer
{
Quit x + y
}
An example of a method that creates and returns an object instance is:
Method FindPerson(id As %String) As Person
{
Set person = ##class(Person).%OpenId(id)
Quit person
}
Instance methods can be either public or private. If private (specified
with the PRIVATE keyword), they can only be accessed by methods of any instance
of the class to which they belong; if public (the default), they can be accessed
from any method or other call.
Class methods can only be public. A class method using the PRIVATE keyword
is still accessible from all methods or other calls; however, it does not
appear in the generated
Caché Class Reference.
In Caché, private methods are inherited and visible to subclasses
of the class that defines the method. Other languages often call these protected
methods.
You have the choice of implementation language when creating a method
within Caché. Currently, there are three options:
Cache(Caché
ObjectScript),
Basic, and
Java.
By default, a method uses the language specified by its class'
Language keyword. You can override this
on a method-by-method basis using the method's
Language keyword:
Class MyApp.Test {
/// A Basic method
Method TestB() As %Integer [ Language = basic]
{
'This is Basic
Print "This is a test"
Return 1
}
/// A Cache ObjectScript method
Method TestC() As %Integer [ Language = cache]
{
// This is Cache ObjectScript
Write "This is a test"
Quit 1
}
}
Within a class, it is possible to have methods implemented in different
languages. All methods interoperate regardless of implementation language.
Caché ObjectScript and Basic methods are compiled into executable
Caché code; Java methods are treated differently. When you create a
Java representation of a class (using the
Caché Java
Binding), all of its Java methods are generated directly within the
Java source. This means that all Java methods run within a native JVM and
have access to the complete Java environment.
You can modify a method definition through the use of one or more method
keywords. Each keyword is optional and has a default value if not explicitly
specified.
The major method keywords are:
Specifies that the method is a class method. By default, methods are
instance methods. Subclasses inherit and cannot modify the value of the
ClassMethod keyword.
Provides an optional description of the method; Caché does not
use this description. By default methods have no description. Subclasses do
not inherit the value of the
Description method keyword.
Specifies that subclasses cannot override the method. By default, methods
are not final. The
Final method keyword is inherited
by subclasses.
Specifies that the method can only be invoked by other methods of its
class or subclasses. (If a method is not private, there are no restrictions
on where it can be invoked.) Subclasses inherit the methods as private and
can modify the value of the keyword. By default, a method is public. (Note
that other languages often use the word protected to describe
this kind of visibility and use private to prevent visibility
from subclasses.)
Specifies the data type of the value returned by a call to the method.
Setting
ReturnType to an empty string ("") specifies
that there is no return value.
The value of the
ReturnType keyword is inherited
by subclasses and can be modified by subclasses. If you do override the value
of the
ReturnType keyword, you are limited to changing
it to a class that is a subclass of the original type.
By default, a method has no return value.
Specifies that the method is an SQL stored procedure. By default, a
method has no stored procedures. Stored procedures are inherited by subclasses.
Instance and Class Methods
Generally, the term
method refers to an instance method,
which is a method that is invoked from a specific instance of a class that
performs some action related to that instance, such as performing business
logic, displaying information about the instance, and so on. For example,
suppose you have an instance of the
Sample.Person class
(included in the
Samples namespace) in memory called
MyPerson;
you can then invoke its instance methods, such as its
NinetyNine method
(a example method that simply returns the value 99):
Set x = MyPerson.NinetyNine()
This line of code uses the
NinetyNine method
to set
x equal to 99.
In addition to instance methods, Caché supports class methods.
A class method is not necessarily associated with a particular object and
need not be invoked from an open object. As such, you can invoke a class method
in either of two ways:
-
Without any object reference
-
From a specific instance in order to act on one or more objects
of the class
A class method can refer to other class methods, but cannot refer to
any object properties or instance methods. For example:
Set x = ##class(Invoice).%Open(oid)
Set x = ##class(Patient).%New()
The first example involves the
%Open class
method of the
Invoice class, which takes the OID of
a particular instance, opens that instance, and returns a handle to it; the
second example uses the
Patient class' the
%New method
to create a new
Patient instance and return a handle
to it.
Class methods are important because you can invoke them without having
an instance that is already open. For example, you can use the
%New and
%OpenId class
methods to create or open an instance. Class methods are also useful for actions
that involve multiple or all instances of a class.
Caché supports four types of methods:
The various method types control how the Caché class compiler
interprets the Implementation of the method.
A code method is a method whose implementation is simply lines of code.
This is the most typical type of method and is the default.
For instance, the following method defines a
Speak code
method for the
Dog class:
Class MyApp.Dog Extends %Persistent [ClassType = persistent]
{
Method Speak() As %String
{
Quit "Woof, Woof"
}
}
The method code can contain any valid Caché ObjectScript code
(including embedded SQL and embedded HTML) or Basic code (depending on the
method's
Language keyword).
Assuming
dog refers to a
Dog object,
you could invoke this method as follows:
Write dog.Speak() // yields: Woof, Woof
An expression method is a method that may be replaced by the class compiler,
in certain circumstances, with a direct in-line substitution of a specified
expression. Expression methods are typically used for simple methods (such
as those found in data type classes) that need rapid execution speed.
For example, it is possible to convert the
Speak method
of the
Dog class from the previous example into an
expression method:
Method Speak() As %String [CodeMode = expression]
{
"Woof, Woof"
}
Assuming
dog refers to a
Dog object,
this method could be used as follows:
Which could result in the following code being generated:
It is a good idea to give all formal variables of an expression method
default values. This prevents potential inline substitution problems caused
by missing actual variables at runtime.
Note:
Caché does not allow macros or call-by-reference arguments within
expression methods.
A call method is a special mechanism to create method wrappers around
existing Caché routines. This is typically useful when migrating legacy
code to object-based applications.
Defining a method as a call method indicates that a specified routine
is called whenever the method is invoked. The syntax for a call method is:
Method Call() [ CodeMode = call ]
{
Tag^Routine
}
A method generator is actually a small program that is invoked by the
Class Compiler during class compilation. Its output is the actual runtime
implementation of the method. Method generators provide a means of inheriting
methods that can produce high performance, specialized code that is customized
to the needs of the inheriting class or property. Within the Caché
library method generators are used extensively by the data type and storage
classes.