Category: Application Packages

Arrays Question

This post is to address a question posed in one of the comments on another post.  The answer is a little too in-depth for a comment reply.  Also, I had been wanting to blog more about arrays anyway.

Here is the question:

Hi i have seen your comment on Arrays.
i need your guidence on creating array and using it in Peoplecode App package.
I have some logic written in SQR. Same thing i want create in App Package which can be used.
Let me brief you my requirement.
i have several parameters to be stored in an array which i will get from different validations and SQL tables for employees.which i will store it in a array. After finishing validations for all the employees i have pass those employee id and details some other system so i want to replicate in App package using Array can you guide me how i can design it in App package.

I also decided to use my step-by-step that I just completed.  So, this answer will build on that post.

Listening to the requirements, I don’t think that we need to extend the array object like the post that this comment was on.  At most, I think we might want to create an employee object that will store all of the fields (or parameters as the requirements call them) needed.

So, I am creating a new Application Package called BLG_BLOGGING.  Then, I am inserting a new Application Class called “EmployeeObject”:

Then, I created three properties in that class to hold three parameters relating to an employee.  I did not specify the “get” or “set” keywords so I don’t have to create getter and setter methods.  This is the easiest way to add properties to a class because you don’t have to write any code for the properties.  Here is the code:

class EmployeeObject
   property string EmployeeID;
   property string FirstName;
   property string LastName;
end-class;

Then, in the Application Engine program, you have to import your new class.  This statement does nothing more than tell the program you are going to use this class later on.

import BLG_BLOGGING:EmployeeObject;

Here are the different variables that we will need.

Local File &log;
Local BLG_BLOGGING:EmployeeObject &emp;
Local array of BLG_BLOGGING:EmployeeObject &ary;
Local number &x;

This code creates an empty array.  We need to pass it a copy of the employee object just so it knows what data type will be stored in the array.  It will not actually store anything in the array at this point.

&emp = create BLG_BLOGGING:EmployeeObject();
&ary = CreateArrayRept(&emp, 0);

Here is where we load the first employee into the array.  We set all of the properties, and then, we use the push() method to insert it into the array.

&emp.EmployeeID = "001";
&emp.FirstName = "Bob";
&emp.LastName = "Tomato";
&ary.Push(&emp);
&log.WriteLine("Added Bob Tomato -- length = " | &ary.Len);

Then, we repeat that with another employee.

&emp = create BLG_BLOGGING:EmployeeObject();
&emp.EmployeeID = "002";
&emp.FirstName = "Larry";
&emp.LastName = "Cucumber";
&ary.Push(&emp);
&log.WriteLine("Added Larry Cucumber -- length = " | &ary.Len);

Finally, we add a third employee just to give us some data.

&emp = create BLG_BLOGGING:EmployeeObject();
&emp.EmployeeID = "003";
&emp.FirstName = "Lunt";
&emp.LastName = "Squash";
&ary.Push(&emp);
&log.WriteLine("Added Lunt Squash -- length = " | &ary.Len);

Then, we need to loop through the array to show what it contains.  The Get() method accesses one of the elements in the array.  It does not remove the element from the array.

&log.WriteLine("");
&log.WriteLine("Employees: ");
For &x = 1 To &ary.Len
     &emp = &ary.Get(&x);
     &log.WriteLine("  " | &emp.EmployeeID | ") " | &emp.LastName | ", " | &emp.FirstName);
End-For;

Final Solution

Here is the Application Package, Employee Object:

class EmployeeObject
   property string EmployeeID;
   property string FirstName;
   property string LastName;
end-class;

Here is the App Engine Program:

import BLG_BLOGGING:EmployeeObject;

Local File &log;
Local BLG_BLOGGING:EmployeeObject &emp;
Local array of BLG_BLOGGING:EmployeeObject &ary;
Local number &x;

&log = GetFile("c:\temp\log.txt", "W", "A", %FilePath_Absolute);

&emp = create BLG_BLOGGING:EmployeeObject();
&ary = CreateArrayRept(&emp, 0);

&emp.EmployeeID = "001";
&emp.FirstName = "Bob";
&emp.LastName = "Tomato";
&ary.Push(&emp);
&log.WriteLine("Added Bob Tomato -- length = " | &ary.Len);

&emp = create BLG_BLOGGING:EmployeeObject();
&emp.EmployeeID = "002";
&emp.FirstName = "Larry";
&emp.LastName = "Cucumber";
&ary.Push(&emp);
&log.WriteLine("Added Larry Cucumber -- length = " | &ary.Len);

&emp = create BLG_BLOGGING:EmployeeObject();
&emp.EmployeeID = "003";
&emp.FirstName = "Lunt";
&emp.LastName = "Squash";
&ary.Push(&emp);
&log.WriteLine("Added Lunt Squash -- length = " | &ary.Len);

&log.WriteLine("");
&log.WriteLine("Employees: ");
For &x = 1 To &ary.Len
     &emp = &ary.Get(&x);
     &log.WriteLine("  " | &emp.EmployeeID | ") " | &emp.LastName | ", " | &emp.FirstName);
End-For;

&log.Close();

Here is the final output:

Added Bob Tomato -- length = 1
Added Larry Cucumber -- length = 2
Added Lunt Squash -- length = 3

Employees:
  001) Tomato, Bob
  002) Cucumber, Larry
  003) Squash, Lunt

Response: Array Class Generic Sort

Here is my attempt at providing details in response to an article by ChiliJoe called PeopleCode Array Class’ Generic Sort.

Basically, ChiliJoe is referring to a vague example in PeopleBooks that says, “For example, suppose you want to provide a more generic sort, with comparison function at the end of it.” This is in the section: “When Would You Use Application Classes?“.

The key to this example is that you have to write the sort by extending the array class. Here is an attempt at writing an example:

Read More

Response: Private/Instance Variables

ChiliJoe posted in Access to Instance Variables within the Same Class that an instance can change the value of another instance’s private variable.

At first, this sounds like it doesn’t make sense — an instance shouldn’t be able to access something private to another instance. But, in my opinion, the private is to protect it from code that may not understand or may violate rules the class depends on. From that point of view, it does make sense. Whoever wrote the code for the class knows what the value should be, and therefore, can be trusted to change it. Therefore, it can change any instance’s private variable as long as it is the same class. Whoever wrote the other class may not even be able to look at the code to see if they are going to mess things up, and therefore, cannot access the variable.

I think the PeopleSoft names make it confusing. Instead of calling it private, PeopleCode calls it instance, which would lead you to think that only that instance could access it. Actually, it is private to the class, not the instance.

So, to take the challenge, I translated ChiliJoe’s code to Java just to see if it works the same in Java. It does:

package com.skp.peoplecodejavacompare;

public class Example {
private Example newInstance;
private int num = 0;

public void createNewInstance() {
newInstance = new Example();
}

public int incrementNewInstanceNum() {
newInstance.num++;
return newInstance.num;
}

public int incrementThisInstanceNum() {
num++;
return num;
}

public void incrementPassedNum(Example passed) {
passed.num ++;
}

public int getThisInstanceNum() {
return num;
}

public static void main(String[] args) {
Example test1 = new Example();
test1.createNewInstance();

System.out.println(“incrementNewInstanceNum returns “ + test1.incrementNewInstanceNum());
System.out.println(“getThisInstanceNum returns “ + test1.getThisInstanceNum());
System.out.println(“incrementThisInstanceNum returns “ + test1.incrementThisInstanceNum());
System.out.println(“incrementNewInstanceNum returns “ + test1.incrementNewInstanceNum());

Example test2 = new Example();
System.out.println(“test2.getThisInstanceNum returns “ + test2.getThisInstanceNum());
test1.incrementPassedNum(test2);
System.out.println(“test2.getThisInstanceNum returns “ + test2.getThisInstanceNum());
}
}

Output:

incrementNewInstanceNum returns 1
getThisInstanceNum returns 0
incrementThisInstanceNum returns 1
incrementNewInstanceNum returns 2
test2.getThisInstanceNum returns 0
test2.getThisInstanceNum returns 1

PeopleTools Bug

If you are coding an Application Package, and you get this error message:

PeopleTools Affirm Triggered
PSAFFIRM(!pItemFound) failed at e:\pt846-908-r1-retail\peopletools\src\inc\stringhash.h, line 157. See trace file. Press Cancel for debugger.

Here is the solution:

Basically, you have a property with the same name as one of your instance variables. For example:

class ExampleClass
method ExampleClass();
property String ExampleDescription get set;
private
instance String &ExampleDescription;
end-class;

To fix the problem you can change it to:

class ExampleClass
method ExampleClass();
property String ExampleDescription get set;
private
instance String &strExampleDescription;
end-class;