Table of Contents
Previous Section
In WebScript, the scope of variables depends on where and how you declare them. The notion of scope in WebScript really encompasses two different ideas: a variable's visibility and its lifetime.
The simplest kind of variable in WebScript is a local variable, which is declared inside a method as follows:
- aMethod {
id localVar;
/*...*/
}
Local variables have no visibility outside the method in which they're declared, and no lifetime beyond the method's execution. For this reason, they're the only type of variable that can't be referenced in a declarations file.
All other variables have some degree of persistence within your application. To understand the role of these variables, it's useful to think about the flow of activity in a WebObjects application. The life of a WebObjects application is marked by the continual recurrence of requests (such as a user clicking a control to initiate an action), and the subsequent responses (such as the server returning a dynamically generated HTML page in response to a request). A request-response cycle is called a transaction. Processing and variable scoping in a WebObjects application is organized around transactions.
Non-local variables behave differently depending on whether they're declared in an application script (where they're called global and session variables) or in a component script (where they're called transaction and persistent variables).
Global variables can be accessed from all pages of an application, and they last for the duration of an application. A global variable is available across all sessions, and there is one copy of the variable per application. Global variables are declared in the application script outside a method as follows:
id globalVar;
Whereas all users of an application see a global variable with the same value, each session has its own version of session variables. A variable with session scope lasts for the duration of a session. A session represents a browser (user) accessing a WebObjects application, which could be serving multiple users. A session is initiated when a browser (single user) connects to a WebObjects application, at which time the session is assigned a unique identifier. This session ID is embedded in the URLs of the pages associated with the application. The session ID lasts as long as the session is valid. A session is terminated either when the user quits out of his or her browser, or when the application explicitly times the session out. For more information on session time out, see the section Setting Session Time Out in the chapter "Managing State."
A session variable is accessible from every component script. Its value is stored and restored at the beginning and the end of each request/response cycle. There is one copy of the variable per user session. Session variables are declared in the application script outside a method as follows:
session id sessionVar;
Note that because the WOWebScriptApplication object owns global and session variables, in a component script you access those variables by sending a message to the application:
id value = [WOApp mySessionVariable]; [WOApp setMyGlobalVariable:newValue];
A transaction variable is declared in a component script outside a method, as follows:
id myVar;
A variable with transaction scope lasts for the duration of a transaction, or HTML request. A transaction is defined as a request coming in and a response (usually an HTML page) going out. By the time the response is returned to the client, the variable's value is no longer preserved. Transaction variables are visible to all of the methods within the script in which they're declared.
A persistent variable is declared in a component script outside a method using the persistent keyword, as follows:
persistent id myVar;
A persistent variable remains valid for a particular page for the duration of a session. It is stored right before a response is generated for a user request and restored when the client performs an action on the new page.
Whenever possible, you should refrain from using session and persistent variables since they tend to degrade performance. It's preferable to programmatically recreate variables in the script's awake method instead of declaring them as session or persistent, for example:
id myLinks; // just use a regular transaction variable...
// ... then re-initialize it in the script's awake method
- awake {
myLinks = @("My Autobiography", "Pictures of my Dog");
return self;
}
There are two cases in which you should use session and persistent variables:
It's important to remember that pages aren't persistent in an application. They are created at the beginning of a transaction, and they disappear at the end. The life of a page actually spans two transactions:
Between these two occurrences, the WOWebScriptComponentController associated with a page is destroyed and reconstructed. Any variables in your application that aren't declared as persistent, session, or global are lost. Consequently, variables whose values the page depends on need to be either made persistent or recreated in awake. The preferred approach is to recreate them in awake, as described in the preceding section.
There is one significant exception to the general statement that pages aren't persistent. If an application has caching enabled (which can be achieved either by running the application from the command line with the -c option or by using WOApplication's setCachingEnabled: method), transaction variables will behave exactly like global variables. In other words, users could potentially see transaction variables with the values assigned to them by other users. For this reason, it's good practice to reinitialize transaction variables in your script's awake method.