Legacy Code Part 11: Pass It Along

One thing that affects application performance, in your Legacy Code, could be a lack of (or misuse of) variable scoping. In our last post we discussed the usage of the various persistent scopes. Now, we'll talk about some of the other scopes that your application might be using.

In this post, we'll get the easy one's out of the way. It's really all in the name, for many of these, which I like to call the passalong variables.

- These are the variables from the url query string. Not the most secure way to pass around information, but some variables don't always require protection. It is typically good practice to <cfparam> url variables, on the off chance that the link was truncated.
view plain print about
2    param name="URL.debug" type="boolean" default=false;
- These variables are available to a template that is the target of a form post. It is made up of all of the form field names and values passed in a post, and includes a special "fieldnames" key as well, that contains a comma delimited list of all of the passed form fields. It is important to note that browsers do not pass checkbox fields that are unchecked, so it is always a good idea to <cfparam> any checkbox fields.
view plain print about
2    param name="FORM.categoryid" type="numeric" default=0;
- These are variables that are passed into a function method, for use within the function. When you need a variable in a function, from outside of that function (for instance, a persistent scope variable), you want to pass the variable into the function as an argument. This will help to prevent memory leaks, maintain encapsulation, and manage dependencies. A bonus is that you can use the argument definition in the method signature in a way similar to <cfparam>, by providing a default value.
view plain print about
3 * @access public
4 * @output false
5 * @returntype void
6 */

7function setUser (required string firstName, required string lastName, boolean isActive=true) {
8 // Your code goes here
It is always important to declare the argument's type in the method signature (as in <cfparam>), as it will assist in the overall security of your application by ensuring that methods receive the proper variable type.
- The attributes scope is the arguments scope of custom tags. Similar rules should apply, in that if you require data from another scope, within your custom tag, then best practice is to pass the variable in as an attribute of the tag. Just like <cfargument> and <cfparam> you can (and should) define a type for the variable, as well as a default value if necessary.

Quick author's note here: You'll notice, in my code examples, that I use the <cfscript> form of code, while referencing the <tag> form in my dialog. Most Legacy Code is tag based, but you will find more and more core business logic is written in scripted form. Each scripted block can be done in tag form, but I personally stay away from tag based code for anything other than view templates and any inline looping or conditionals of that view code.

In our next post we'll discuss the remaining scopes. These include some of the more tricky scopes used within CFCs and Custom Tags, as well as a few others.

This article is the eleventh in a series of articles on bringing life back to your legacy ColdFusion applications. Follow along in the Legacy Code category.

Legacy Code Part 10: Be Persistent

As I said in my last post, scoping all of your variables can be a huge performance improvement for your dated Legacy Code. By explicitly scoping each and every variable reference, within your application, you eliminate the overhead of the system having to ScopeCheck each reference to determine it's scope. Understanding usage of each scope is an important part of this process. In this post, we'll discuss the persistent scopes of an application.

- This scope is valuable in environments where you have a dedicated server for your applications. Use carefully, and sparingly, this is a good place to put crafted objects and variables that can be shared across multiple applications in a shared server. Multi-Site One Codebase setups can get significant use of the SERVER scope, for housing things like utility objects that can be used by each application, without duplicating them in each app. The downside is, any change to a SERVER scoped object or variable will require a server restart to take effect. You can set these variables in onServerStart() method of the Server.cfc.
- This scope is valuable for creating Application wide objects and variables, that can be used regardless of individual user sessions. This is typically a good place for utility objects (if they aren't in the SERVER scope), asset pathing references, logging objects, and more. Typically you initialize these variables in the onApplicationStart() method of your Application.cfc, and only change these variables when making application wide changes, realizing that those changes will affect all current users.
- This scope is used for storing variables only used by a single user's browsing session. This is a good place for storing things like a user object, and shopping carts. Things that are only used for and by a single user, within their current visit to your application. You typically create these variables in the onSessionStart() method of your application's Application.cfc, and you can manipulate SESSION variables during a request, remembering that those changes will affect the remainder of the user's session.
- This scope is used for storing variables only used within the current page request. While a REQUEST variable is available to every template called during the course of a request, it is not best practice to directly access REQUEST variables inside of cfc's or custom tags, but rather to pass them in as a method argument or tag attribute, respectively, in order to maintain encapsulation. These variables are great for storing page specific details for use throughout the request, such as setting a page title, and using it at request end to log the page viewed by the user. Requests typically come in three parts: onRequestStart(), which occurs before the templates execute, onRequestEnd(), which occurs after the requested template executes, and either onRequest() or onRequestCFC(), which allow for some additional pre-template processing, but segment it according to what is being requested. To understand these last two a little further, onRequest() might be used to set a variable to tell the system to log the request on completion, whereas onRequestCFC might set the same variable to tell the system to not log the request (because you don't need to log direct CFC execution, maybe). These last two can be powerful, and confusing, so you might have to play with them a bit, if you want to use them at all. You use any, or all, of those methods within your application's Application.cfc.

SERVER, APPLICATION, SESSION, and REQUEST are ColdFusion's persistent scopes, allowing for the creation and use of variables that can be used across very defined measures of time. In our next post, we'll talk about how you should use the other scopes in CF.

This article is the tenth in a series of articles on bringing life back to your legacy ColdFusion applications. Follow along in the Legacy Code category.