UDF structure

an article added by: Nina Lachey at 04042008


In: Categories » Computers and technology » Programming » UDF structure

ColdFusion has more than 250 functions in its language. It has string-manipulation functions, array functions, structure functions, and many other types of functions. Even with this wide variety of functions, however sometimes you may want to define your own function that does things that the built-in ColdFusion functions can’t. This article does not describe how to use CFSCRIPT—only how to use CFSCRIPT in conjunction with user-defined functions. A user-defined function, or UDF, can be built in CFSCRIPT, CFML, or a combination of the two. The following parts describe how to build UDFs by using CFSCRIPT. CFSCRIPT UDFs are very natural because they mimic function creation in JavaScript, Java, and many other programming languages which you may already be familiar with. In general, functions receive one or more arguments and return a single result. Some functions (such as ColdFusion’s Now() function) do not take arguments, but almost all functions do return a result. A basic UDF built by using CFSCRIPT looks as follows:

<cfscript>
   function GetCurrentTime() {
   return TimeFormat(Now(), “h:mm:ss tt”);
   }
 </cfscript>

The only four things required for every function are the function keyword, the name of the function, the parentheses after the name, and the curly braces around the body of the function. Although the return statement is technically optional, return is what makes a function truly useful, as this statement represents the result returned to the code that calls the function. We call the function that we just created as we would any built-in ColdFusion function, as follows:

<cfoutput>#GetCurrentTime()#</cfoutput>

We can expand my function by defining a local variable, as follows:

function GetCurrentTime() {
   var szTime = TimeFormat(Now(), “h:mm:ss tt”);
   return szTime;
   }

More on the var keyword in the following part. We can also add code to our function between the variable declaration and the return statement, as follows:

function GetCurrentTime() {
   var szTime = TimeFormat(Now(), “h:mm:ss tt”);
   szTime = ReplaceNoCase(szTime, “am”, “in the morning”);
   szTime = ReplaceNoCase(szTime, “pm”, “in the evening”);
   return szTime;
   }

This UDF is a very simple example that doesn’t take any arguments. Now to take a look at var in more detail. var declares a variable that’s local to a function. If we didn’t use var, for example, we could do the following:

<cfscript>
   function myFn() {
   myVar = 1;
   return TRUE;
   }
 </cfscript>
 <cfoutput>
 #myFn()#
 #myVar#
 </cfoutput>

After you call myFn(), myVar is available to code outside the function. That’s because any variable defined inside CFSCRIPT is also available to CFML. This is very sloppy programming because you could be inadvertently creating or overwriting variables you weren’t intending to affect. To keep myVar local to myFn() such that it can’t leak outside the function, use var, as follows:

<cfscript>
   function myFn() {
   var myVar = 1;
   return TRUE;
   }
 </cfscript>

Now, attempting to use myVar outside myFn() throws an error, which is exactly what you want it to do. All variables created by using var must be initialized; ColdFusion throws an error if they are not. And notice, too, that you cannot place the var keyword anywhere other than at the very top of a function declaration. Functions return a single value, as the following example shows:

function myFn() {
   return TimeFormat(Now(), “h:mm:ss tt”);
   }

As soon as CFSCRIPT encounters a return statement, ColdFusion stops executing the function and returns the value following the return keyword to the calling code. You can also conditionally return different values based on different circumstances, as in the following code:

function myFn() {
   if(IsDefined(“Client.myVar”)) {
   return Client.myVar;
   } else {
   return TimeFormat(Now(), “h:mm:ss tt”);
   }
   }

Every control path in a function must return a value or you get inconsistent results. A best practice, therefore, is to define a default return value and use only one return statement in your function declaration, as follows:

function myFn() {
   var result = TimeFormat(Now(), “h:mm:ss tt”);
   if(IsDefined(“Client.myVar”)) {
   result = Client.myVar;
   }
   return result;
   }

Most functions take one or more arguments, as the following example shows:

<cfscript>
   function add2(firstNumber, secondNumber) {
   return firstNumber + secondNumber;
   }
 </cfscript>
 <cfoutput>
 #add2(1,2)#
 </cfoutput>

The argument names are defined in a list inside the parentheses after the function declaration. You see more advanced uses of arguments later in this article. The preceding example used positional arguments, meaning that the first argument in the function call was passed to the first argument in the function, the second in the call became the second in the function, and so on. You can also name the arguments in the call if you want to pass them in a different order, as follows:

<cfoutput>
   #add2(secondNumber=2,firstNumber=1)#
 </cfoutput>

This syntax is not widely used because it is slightly harder to read; it can help you, however, if you don’t remember the order of a function’s parameters. If any of a function call’s arguments are named, however, all the arguments must be named. Functions can be called anywhere within a ColdFusion template, even from within another ColdFusion function. Take the following example:

<cfscript>
   function myFn(myNum, yourNum) {
   return myNum * yourNum;
   }
   function myOtherFn() {
   var num1 = RandRange(1,10);
   var num2 = RandRange(1,10);
   return myFn(num1, num2);
   }
 </cfscript>

A function can also call itself. We wrote the following function, for example, to calculate the factorial of a number (a factorial will be defined in a moment):

<cfscript>
   function Factorial(myNum) {
   if(myNum EQ 1) {
   return 1;
   }
   else {
   return myNum * Factorial(myNum - 1);
 </cfscript>
 <cfoutput>#Factorial(6)#</cfoutput>

The factorial of 6, for example, is 6 x 5 x 4 x 3 x 2 x 1, or 720. To calculate the factorial, we return the number passed to the function, multiplied by the next smaller factorial (because the 6 factorial can also be represented as 6 x 5 factorial). You must be careful in creating recursive functions to make sure that you have a stop condition. In our case, we stop the recursion whenever myNum is 1. If you don’t build a stop condition into your logic, you put the request into an infinite loop. We show you that structures are accessed by reference, whereas other variables are referenced by value. The same applies to passing variables to a function. If you pass a number to a function, the function has a local copy of that number, and any modifications that functions makes to the number are not repeated outside the function call. Structures are passed to a function by reference, however, so any modifications that the function makes to the structure parameter can be seen outside the function call.

legal notice

Our website is not responsible for the information contained by this article. Web-articles is a free articles resource.
Suggestion: If you need fresh, daily updated content for your website, feel free to use our service. Click here for more information.

Useful tools and features

Link to this article from your page    Send this article to you or to a friend
If you like this article (tutorial), please link to it from your web page using the information above.

related articles

1. Building the company edit action template
The code in CompanyEditAction.cfm is like the code in CompanyAddAction.cfm, but the edit action updates rather than inserts. Create a file named CompanyEditAction.cfm inside the Ch02 directory, type the code into the file’s editing window, and save the file. <cfquery name=”UpdateCompany” datasource=”#Request.MainDSN#”> UPDATE Company SET CompanyName = ‘#Trim(Form.CompanyName)#’, Address = ‘#Trim(Form.Address)#’, City = ‘#Trim(Form.City)...

2. Adding a New Employee to the Database
The CFQUERY in CompanyDeleteAction.cfm uses a DELETE statement with two SQL clauses: DELETE and WHERE. DELETE tells the database the table from which to delete a record, and WHERE tells the database which record to delete. You can watch the company delete process in action. Point your Web browser to http://<yourserver>/CFMXBible/Ch02/CompanyGetDeleteForm.cfm and enter a CompanyID. (To get a valid ID, go to the company list and pick a number from the ID column.) Click Submit to see the chosen company’s informatio...

3. Modifying an Employee in the Database
The DateFormat() function around the DateOfBirth column in the codereturns the employee’s birth date reformatted according to a display mask. DateOfBirth normally comes back from the database in the following format: 2002-01-01 00:00:00.0 That format is not very user-friendly. Calling DateFormat() with a mask of “mm/dd/yyyy” returns the date as follows: 01/01/2002 This version is, of course, more natural and easy to read. The same is true for the employee edit process...

4. Removing an Employee From the Database
The user must have the capability to remove employees from the database. The employee delete process is a simple combination of techniques that you have already learned, such as retrieving a record from the database, displaying that record in a template, and so on. The first page in this process is nearly identical to the employee get edit form. Create a file named EmployeeGetDeleteForm.cfm inside the Ch02 directory, type the code into the file’s editing window, and save the file. <html> <head> <ti...

5. Making direct links to the forms
Say that you want to modify or delete a company. Right now, you need to remember the company’s ID, go back to the launch pad, click Company Edit, and enter the company ID, all just to get to the edit form. Wouldn’t you rather click a company in the list and go directly to the edit form? ... <table> <tr> <td><b>ID</b></td> <td><b>Name</b></td> <td><b>Address</b></td> <td><b>City</b></t...

6. Using a Custom Tag
Custom tags are reusable, developer-authored extensions to the ColdFusion language. The custom tag that you create in the following parts displays today’s date in a familiar format. Create a file named TodaysDate.cfm inside the Ch02 directory, type the code into the file’s editing window, and save the file. <cfoutput>#DateFormat(Now(), “ddd, mmm d, yyyy”)#</cfoutput> Now() returns the current date and time, and DateFormat() reformats the date. To call your custom tag, open index.cfm, a...

7. Creating your physical data model
Physical data models are extracted from their logical counterparts by mapping logical objects to physical objects supported by the target database platform. The following table shows the relationship between logical and physical objects. In many cases, your physical data model almost mirrors your logical data model because entities typically map directly to the tables that store them. Exceptions to this rule are logical data models that contain nonspecific relationships and entity subtypes. Although entity subtypes are an advanced top...

8. Understanding All Relational Result Sets
This article can help you better understand complicated SQL containing multitable joins, group-related clauses, and aggregate functions—by far the most problematic topics for most database developers. You also learn the correct way to handle database exceptions and incorporate them as actual functionality in your ColdFusion application. You learn, too, how to increase performance by caching queries in memory for fast access. You can memorize SQL clauses and Bachus-Naur forms until you’re blue in the face, ...