PUB

Designator: Declare a Public Method Block.

((PUBPRI))
  PUB Name < (Param <, Param >…) > <: RValue > <| LocalVar < [Count ] >> <, LocalVar < [Count] >>…
    SourceCodeStatements

  • Name is the desired name for the public method.
  • Param is a parameter name (optional). Methods can contain zero or more comma-delimited parameters, enclosed in parentheses. Param must be globally unique, but other methods may also use the same symbol name. Each parameter is essentially a long variable and can be treated as such.
  • RValue is a name for the return value of the method (optional). This becomes an alias to the method's built-in RESULT variable. RValue must be globally unique, but other methods may also use the same symbol name. The RValue (and/or RESULT variable) is initialized to zero (0) upon each call to the method.
  • LocalVar is a name for a local variable (optional). LocalVar must not have the same symbol name as any VAR or CON symbol, but other methods may also use the same symbol name. All local variables are of size long (four bytes) and are left uninitialized upon each call to the method. Methods can contain zero or more comma-delimited local variables.
  • Count is an optional expression, enclosed in brackets, that indicates this is a local array variable, with Count number of elements; each being a long in size. When later referencing these elements, they begin with element 0 and end with element Count-1.
  • SourceCodeStatements is one or more lines of executable source code that perform the function of the method; usually indented by at least two spaces for readability.

Explanation

PUB is the Public Method Block declaration. A Public Method is a section of source code that performs a specific function then returns a result value. This is one of six special declarations (CON, VAR, OBJ, PUB, PRI, and DAT) that provide inherent structure to the Spin language.

Every object can contain a number of public (PUB) and private (PRI) methods. Public methods can be accessed outside of the object itself and serve to make up the interface to the object.

The PUB and PRI declarations don't return a value themselves, but the public and private methods they represent always return a value when called from elsewhere in the code.

Public Method Declaration

Public Method declarations begin with PUB, in column 1 of a line, followed a unique name and an optional set of parameters, a result variable, and local variables.

Example:

PUB Init
  <initialization code>

PUB MotorPos : Position
  Position := <code to retrieve motor position>

PUB MoveMotor(Position, Speed) : Success | PosIndex
  <code that moves motor to Position at Speed and returns True/False>

This example contains three public methods, Init, MotorPos and MoveMotor. The Init method has no parameters and declares no return value or local variables. The MotorPos method has no parameters but declares a return value called Position. The MoveMotor method has two parameters, Position and Speed, a return value, Success, and a local variable, PosIndex.

All executable statements that belong to a PUB method appear underneath its declaration. By convention these lines are indenteded by two spaces for readability, but this is not required for functionality. (However, indention is critical for certain command blocks, such as REPEAT and IF.)

The Return Value

Whether or not a PUB declaration specifies an RValue, there is always an implied return value that defaults to zero (0). There is a pre-defined name for this return value within every PUB method, called RESULT. At any time within a method, RESULT can be updated like any other variable and, upon exiting the method, the current value of RESULT will be passed back to the caller. In addition, if a RESULT is declared for the method, that name can be used interchangeably with the built-in RESULT variable. For instance, the MotorPos method above sets "Position := …" and could also have used "Result := …" for the same effect. Despite this, it is considered good practice to give a descriptive name to the return value (in the PUB declaration) for any method whose return value is significant. Likewise, it is good practice to leave the return value unnamed (in the PUB declaration) for any method whose return value is unimportant and unused.

Parameters and Local Variables

Parameters and local variables are all longs (four bytes). In fact, parameters are really just variables that are initialized to the corresponding values specified by the caller of the method. Local variables, however, are not initialized; they contain random data whenever the method is called.

All parameters are passed into a method by value, not by reference, so any changes to the parameters themselves are not reflected outside of the method. For example, if we called MoveMotor using a variable called Pos for the first parameter, it may look something like this:

Pos := 250
MoveMotor(Pos, 100)

When the MoveMotor method is executed, it receives the value of Pos in its Position parameter, and the value 100 in its Speed parameter. Inside the MoveMotor method, it can change Position and Speed at any time, but the value of Pos (the caller's variable) remains at 250.

If a variable must be altered by a routine, the caller must pass the variable by reference; meaning it must pass the address of the variable instead of the value of the variable, and the routine must treat that parameter as the address of a memory location in which to operate on. The address of a variable, or other register-based symbol, can be retrieved by using the Symbol Address operator, '@'. For example,

Pos := 250
MoveMotor(@Pos, 100)

The caller passed the address of Pos for the first parameter to MoveMotor. What MoveMotor receives in its Position parameter is the address of the caller's Pos variable. The address is just a number, like any other, so the MoveMotor method must be designed to treat it as an address, rather than a value. The MoveMotor method then must use something like:

PosIndex := LONG[Position]

...to retrieve the value of the caller's Pos variable, and something like:

LONG[Position] := <some expression> 

...to modify the caller's Pos variable, if necessary.

Passing a value by reference with the Symbol Address operator is commonly used when providing a string variable to a method. Since string variables are really just byte arrays, there is no way to pass them to a method by value; doing so would result in the method receiving only the first character. Even if a method does not need to modify a string, or other logical array, the array in question still needs to be passed by reference because there are multiple elements to be accessed.

Optimized Addressing

In the compiled Propeller Application, the first eight (8) longs that make up the parameters, the RESULT variable, and the local variables are addressed using an optimized encoding scheme. This means accessing the first eight longs (parameters, RESULT, and local variables) takes slightly less time than accessing the ninth, or later, longs. To optimize execution speed, ensure that all local longs used by the method's most repetitive routines are among the first eight. A similar mechanism applies to global variables; see VAR section for more information.

Exiting a Method

A method is exited either when execution reaches the last statement within the method or when it reaches a RETURN or ABORT command. A method may have only one exit point (the last executable statement), or may have many exit points (any number of RETURN or ABORT commands in addition to the last executable statement). The RETURN and ABORT commands can also be used to set the RESULT variable upon exit; for more information see RETURN and ABORT.

Unless otherwise noted, content on this site is licensed under the
Creative Commons Attribution-ShareAlike 4.0 International License.