The following are a couple of I believe not well-known coding standards for PeopleCode that I strictly adhere to. These are something I don’t see most people or teams are adapting, but something I really recommend looking into for the benefits that they offer.
Except for Application Package PeopleCode, the PeopleCode compiler/editor does not require that local variables used by programs are declared. Undeclared variables are automatically allocated the type of Any.
When writing PeopleCode, declare ALL local variables that will be used.
- Declaring the specific type of variable needed improves performance, in contrast with the interpreter always assuming a type of Any. Even if the variable to be declared requires being an Any type, declare it nonetheless (see 4th item below).
- Compile-time validation.
- When variables are declared, the PeopleCode editor can check the compatibility of variables used in an operation, or passed as function arguments.
- For variables pointing to objects, the names of methods and properties can be validated at save time.
- Convenience. For built-in buffer classes (Rowset, Row, and Record), shorthand notation is only allowed for declared variables.
- For programming languages that allow dynamic allocation of variables, it is a common programming error to misspell variable names. However, on the PeopleCode editor, when all variables are consciously declared, it is easy to check for misspelled variable names (see the following illustration). Thus, with this standard in place, this type of coding error would be eliminated.
Take a moment to look at the following PeopleCode example:
This code has 2 misspelled variables. How long did it take you to find them?
The code could be modified to enforce the rule that all variables are consciously declared; resulting in the following (changes are highlighted):
Now, when this PeopleCode is saved, or when the Validate Syntax action () is invoked. The following messages would be displayed in the Output window:
Double-clicking these messages would bring you to the offending line in the code.
NOTE: As shown in the example above, it is NOT necessary to always declare the variable at the top of the program. Declaring them on the first time they are used is sufficient to achieve the said benefits.
When writing SQLExec statements, the common practice is to hard-code table/view names. For example:
SQLExec("Select FIELD1, FIELD2 From PS_RECORD_TBL Where CRITER1 = :1 AND CRITER2 > :2", &IN1, &IN2, &OUT1, &OUT2);
A problem with the above code is that information in the PeopleCode string literals cannot be classified by the compiler and saved into the PeopleTools reference tables.
Use the meta-SQL
%Table() in SQL statements to refer to SQL tables or views.
With a little effort, the above code can be transformed into the following (changes are highlighted):
SQLExec("Select FIELD1, FIELD2 From [b]%Table(:1)[/b] Where CRITER1 = [b]:2[/b] AND CRITER2 > [b]:3[/b]", [b]Record.RECORD_TBL[/b], &IN1, &IN2, &OUT1, &OUT2);
The consequence of this change is that Record.RECORD_TBL is saved as a reference in the appropriate PeopleTools reference table (PSPCMNAME). This brings the following maintenance advantages:
- A Find Definition Reference for RECORD_TBL record will include the above SQLExec line in the results.
- Renaming RECORD_TBL will automatically propagate to the PeopleCode references (App Designer automation). No coding change is required.
- For more complex SQL, like ones that need effective-dated logic, you can reference the record name only once. For example, if RECORD_TBL is effective-dated, you could write the following:
SQLExec("Select FIELD1, FIELD2 From %Table(:1) A Where CRITER1 = :2 AND CRITER2 > :3 [b]And EFFDT = (SELECT MAX(EFFDT) FROM %Table(:1) WHERE KEY1 = A.KEY1 AND EFFDT <= %CurrentDateIn)[/b]", Record.RECORD_TBL, &IN1, &IN2, &OUT1, &OUT2);
- At a glance, the number of tables/views being referenced by the SQLExec can be easily identified.
NOTE: Unfortunately, currently the criteria parameter of the
Select() method of the rowset class does not properly handle the
%Table() meta-SQL, therefore this is one case where you cannot use this standard. Although fortunately, the need to reference a table in the
Select() criteria seldom happens.