|MySQL Conference and Expo April 14-17, 2008, Santa Clara, CA|
Top Ten ColdFusion UDF Tips
5. Make the most of optional parameters
The functionality of many UDFs can be improved by allowing developers to pass
optional parameters to these functions. For example, any time you create a UDF that
manipulates list data, you should allow an optional delimiter to be passed to
the function since not all lists are delimited by commas. Consider the following
The function has two required parameters:
the list (
Because optional parameters are not named, you will have to write code within your
UDF to handle them. A one-dimensional array called
If there are more than two elements in the array, we take the third and use it as the delimiter. The statement
makes the comma the default delimiter in case no third parameter is passed to the function. If for some reason the developer passes in more than three parameters, everything after the third element is ignored.
6. Be careful with recursion
In programming, recursion refers to code that calls itself (we hope) until a certain condition is met. User defined functions are capable of recursion, but it must be used carefully. In the current version of ColdFusion (5.0), recursion is supported to about 800 levels. Going beyond 800 levels is likely to cause a stack overflow and has the potential to destabilize the server, as recursive algorithms tend to be both processor and memory intensive in ColdFusion.
One example typically used to demonstrate recursion is a function used to calculate the factorial (n!) of a number. The factorial is calculated by taking a positive integer (n) and multiplying all of the positive integers between 1 and n. For example, 5!=120 (5x4x3x2x1=120). The UDF for recursively calculating the factorial of a number looks something like this:
A better way to write this function, at least as far as ColdFusion is concerned, is to use a
Writing the function using a
7. By value vs. by reference
Different data types are passed to UDFs in different ways. Strings, numbers, date/time values, and arrays are passed by value. This means that any values passed to the UDF are actually copies of the original value. Any changes made to the value inside the UDF do not result in changes to the original value in the calling template.
Queries, structures, and objects (e.g., COM, CORBA, and Java), on the other hand, are passed
to UDFs by reference. In this case, the value passed to the UDF isn't actually
the value, but rather a pointer to the original value outside of the function.
Because of this, any change made to a value passed by reference results in a
change to the original value back in the calling template. You can avoid having
the original value changed by making a copy of the variable using the
There are certain instances where you can actually pass a variable partially by value and partially by reference. For example, in cases where you pass an array of structures to a UDF, the array is passed by value while each structure in the array is actually a pointer to the original structure.
8. Keep your UDFs organized
One of the great things about UDFs is that you can have more than one in a single template. This gives you the ability to take all of the UDFs that you use in a particular application or Web site and keep them in a single template, commonly referred to as a library. Depending on the number of UDFs used by your application, you may want to create one or more libraries, grouping your UDFs by functionality. The more UDFs you have, the more it makes sense to create multiple UDF libraries.
Here's an example of a small UDF library with several UDFs for calculating the area of various geometrical shapes:
To use any of these functions in any of your templates, all you have to do is
Perhaps the biggest advantage to storing your UDFs in a library has to do with code reuse and ease of management. Using a library gives you a central point from which to manage your UDFs. If you need to make a change to a particular UDF, you need only change it in your UDF library file instead of having to track down each individual template that has the UDF coded inline.
If you find yourself frequently using
9. A word about UDFs and custom tags
Because UDFs exist in the local variable's scope, they are not automatically available within your custom tags. So, if you define or include a UDF in a template that then calls a custom tag which tries to reference that UDF, ColdFusion will throw an error. There are two ways around this. The first is to code the UDF that the custom tag needs in the custom tag template. This makes the UDF available only to the custom tag, and not the template calling it. The second option you have is to copy the UDF to the request scope, thereby making it available to the custom tag and any other templates that are part of the original page request. To copy a UDF to the request scope, the syntax looks like this:
In your custom tag template, to call the
Although both methods of dealing with UDFs within custom tags work, I prefer the first method as it allows you to keep your custom tags portable and self-contained. This is especially true if you distribute your custom tags outside of your organization.
10. Don't reinvent the wheel
The next time you need a UDF for a particular task, you might consider checking to see if one with the desired functionality already exists. The Common Function Library Project is an open source repository of UDFs for ColdFusion that you can download and use in your applications free of charge. The site is run by me and Raymond Camden, a well known ColdFusion author and developer. The site maintains several libraries containing hundreds of functions for everything from string manipulation, statistics, and scientific calculations, to file operations and more. Because it's an open source project, the source code for each function is available unencrypted. In addition, each function comes with documentation as well as an example showing common usage.
The site also contains several tools for working with UDFs, including: the previously mentioned UDFDoc custom tag for auto-generating UDF documentation based on JavaDoc; a ColdFusion Studio (ColdFusion's IDE) extension for interacting with UDFs on the site from directly within Studio; and a UDF generator for automatically generating custom function libraries from the UDFs available on the site.
Because the site is a community project, submissions for new UDFs and improvements to existing UDFs from the ColdFusion community are always welcome. Each UDF submission is tested before being accepted or rejected, ensuring a high level of quality in the available code.
Rob Brooks-Bilson is a freelance writer and a senior technology manager at Amkor Technology. He is the author of O'Reilly's Programming ColdFusion MX, 2nd Edition (covering CF MX 6.1).