Tuesday, April 20, 2010

FUNCLIB's and Event Scoped Variables

While writing code for my post JSON Encoding in PeopleCode, I discovered a need for transient variable persistence (acknowledged in that post). Since I originally wrote that code in a FUNCLIB, I thought I could reuse/persist my JavaObject variables by moving those two variable declarations above the function declaration. What I found was that this had no impact on the behavior of my code. The FUNCLIB function continued to initialize a new instance of my JavaObject variables on each call. Now, PeopleBooks says that JavaObject variables are treated a little differently than other variables so we should test to see if this behavior exists for regular variables, like String variables. To test this, create a FUNCLIB that contains this code:

Local string &test;

Function testval() Returns string
If (None(&test)) Then
&test = "new value";
Return "Not initialized";
Else
Return "Initialized";
End-If;
End-Function;

You can then test this code with a PSUnit test case defined as follows:

import TTS_UNITTEST:TestBase;

class Test extends TTS_UNITTEST:TestBase
method Test();
method Run();
end-class;

Declare Function testval PeopleCode JJM_SCOPE_FUNC.FUNCLIB FieldFormula;

method Test
%Super = create TTS_UNITTEST:TestBase("Test");
end-method;

method Run
/+ Extends/implements TTS_UNITTEST:TestBase.Run +/
Local number &idx;
For &idx = 1 To 10
%This.Msg(&idx | ": " | testval());
End-For;
end-method;

What does PeopleBooks say about this? What should I expect to see? Summarized, any variable declared within an event is available to all functions within that event (take me to the PeopleBooks reference for this). Given this information, the code does work... as described. The variable is accessible by the FUNCLIB function. PeopleBooks does not say the value will persist after a FUNCLIB function returns. It is important to make this distinction. Event scoped variables are accessible by all functions within an event, but they do not persist after leaving the scope of an event. In other words, once a FUNCLIB returns, the event scoped variables are discarded. Of course, if you call a FUNCLIB function from the same event that defines the FUNCLIB function, then the variable value will persist for the duration of the calling function. But if you did that, then the FUNCLIB function wouldn't really be a FUNCLIB function. It would just be a function. By definition, a FUNCLIB function is a function defined in a different event.

My conclusion: Locally scoped variables are really locally scoped. They don't maintain state when a FUNCLIB function returns. For a FUNCLIB, locally scoped variables are only relevant if you plan to call other functions within the FUNCLIB function's event from the FUNCLIB function.

8 comments:

Chili Joe said...

Thanks Jim! I didn't realize it was documented in PeopleBooks as well :)

Ciphersbak said...

Hi Jim,
I've a question here, It may sound ridiculous, but I wanted to know, how do you color your code on your posts!!!

Thank You!

Jim Marion said...

@Ciphersbak, I use the jEdit syntax files you can get from here and the Code2HTML jEdit plugin. What I do is copy my code from App Designer into jEdit, select the custom PeopleCode edit mode, and then use the Code2HTML plugin to convert the code to HTML. For final cleanup, I run the result through HTML tidy online.

I copy/paste the "pre" section from the HTML tidy output into my blogger editor (source view).

The top of the HTML Tidy output has CSS style definitions for the colors. I put those in my blogger template.

Ciphersbak said...

m,

Thanks a lot for your response!!

Regards,
Prashant

Unknown said...

Hi Jim,

We are trying to POST data using integration broker from PeopleSoft Campus sol to 3rd party health care provider. We need to post or send the data in the JSON format to them.

I have looked at the posts and not sure I follow what needs to be done. Could you please let me know as high-level steps in order to acheive the desired results.

We are on Tools 8.53

Thanks
Karthik

Jim Marion said...

@Karthik, PeopleTools 8.53 makes it a lot easier because the Documents module can render a JSON result. What you do is create the service operation and use a document based message as the request. Then you write PeopleCode to populate the Document. If that doesn't work for you, you can always revert to the old way of stringing JSON together. This post contains a JSON encoder in PeopleCode that will ensure strings are safe for JSON.

lifeandshit said...

Jim, is it possible to call CommitWork() in an iScript function. If not do I have any alternatives. I my iscript code I process a report to a pdf format using the ProcessReport() function. When i call CommitWork() after the processreport peoplesoft gives me error "Error committing work. The host environment could not complete the CommitWork() function"

Please I need to find a solution :(

Jim Marion said...

@life... Are you trying to perform a database commit? SQLExec("COMMIT") should work as well. This thread is helpful: http://peoplesoft.ittoolbox.com/groups/technical-functional/peopletools-l/commitwork-and-sqlexeccommit-1414252. iScripts don't have session state or a component buffer, so they behave a little differently.

If you don't have data to commit, then you can ignore the commit.