Definition of Methods
After the declaration of any global or component variables and external functions needed by the methods, comes the actual definition of the methods. This section discusses some of the differences in how application programs are processed by the system, and how application class method parameters are processed.
-
The system never skips to the next top-level statement.
-
Application programs generally pass parameters by value, which is not the same as for existing functions.
-
Parameter passing with object data types is by reference.
-
Application programs use the out specifier to pass a parameter by reference.
Not Skipping to The Next Top-Level Statement
For existing functions and programs, the system skips to the next top-level statement in some circumstances, such as a field not found error. This never happens in an application class program. The code is always executed or an error is produced.
Passing Parameters in Application Class Methods
The parameters to a method are passed by value in the absence of an out specification in the parameter list. However, if a parameter list has an out specification, that argument (when used in the call of a method) must be a value that can be assigned something, and is passed by reference. In particular this means you cannot pass an object property to a method which requires the parameter to be an "out" parameter. Application class properties are always passed by value.
For example:
/* argument passed by reference */
method increment(&value as number out);
/* argument passed by value */
method increment(&value as number);
This is in contrast with existing PeopleCode functions that pass all parameters by reference when they can be assigned something. This means the method signature is a specification of which parameters can be updated by the method. This makes the code easier to debug and maintain because it's easy to see what can be updated and what can't.
The following is an example of code that increments a variable by one.
local Number &Mine;
&Mine = 1;
&obj.Increment(&Mine);
&Mine now has the value 2.
You cannot pass properties by reference. For example, suppose MyProp is a property of class Xan, a statement that requires a reference doesn't work if you supply the property. The following code will always fail because &Xan.MyProp is always passed by value and the MySqlExec method requires it to be passed by reference (so a value can be returned.)
MySqlExec("select from bar", &Xan.MyProp)
This makes sense because the semantics of an object require that you can only change a property with standard property references, not as a side affect of some other action.
Passing Parameters with Object Data Types
Parameters with object data types are always passed by reference:
/* argument passed by reference */
method storeInfo(&f as File);
If you specify the out modifier for a method parameter with an object data type, it becomes a reference parameter. This means that the parameter variable is passed by reference instead of the object that it is pointing at when passed.
For example, if you pass an object parameter with the out modifier:
method myMethod(&arg as MyObjectClass);
local MyObjectClass &o1 = create MyObjectClass("A");
local MyOtherObjectClass &o2 = create MyOtherObjectClass();
&o2.myMethod(&o1);
And inside myMethod this occurs:
Method myMethod
&arg = create MyObjectClass("B");
end-method;
Since the method argument is reassigned within the body of myMethod, &o1 does not point at the new instance of MyObjectClass (initialized with "B") after the method call completes. This is because &o1 still references the original instance of MyObjectClass.
However, if &o1 had been passed with the out modifier, after the method call completes, &o1 points at whatever the parameter was last assigned to; in this case, the new instance of MyObjectClass. The parameter, rather than the object, is passed by reference.
Using the Out Specification for a Parameter
In the following example, a class, AddStuff, has a single public method, DoAdd. This adds two numbers together, then assigns them as different numbers. In the signature of the method declaration, the first parameter is not declared with an out statement, while the second one is.
class AddStuff
method DoAdd(&P1 as number, &P2 as number out);
end-class;
method DoAdd
&X = &P1 + &P2;
&P1 = 1;
&P2 = 2;
end-method;
In the following PeopleCode example, an object named &Aref is instantiated from the class AddStuff. Two parameters, &I and &J are also defined.
local AddStuff &Aref = create AddStuff();
local number &I = 10;
local number &J = 20;
The following code example is correct. &J is changed, because of the out statement in the method signature, and because the value is being passed by reference. The value of &I is not updated.
&Aref.DoAdd(&I, &J); /* changes &J but not &I */
The following code example causes a design time error. The second parameter must be passed by reference, not by value.
&Aref.DoAdd(10, 20); /* error - second argument not variable */
Related Topics