Welcome!

You will be redirected in 30 seconds or close now.

ColdFusion Authors: Yakov Fain, Jeremy Geelan, Maureen O'Gara, Nancy Y. Nee, Tad Anderson

Related Topics: ColdFusion

ColdFusion: Article

Creating and Using User-Defined Functions

A step-by-step guide

An old friend, whom I hadn't seen in over eight years, recently brought an eBay auction to my attention. After some rough times, someone was selling everything he owned so he could start his life completely from scratch. The seller was located in my home state (Connecticut), was a programmer computer-geek, and had long hair. "Jeff, is this you?" was the body of the e-mail.

Of course, it wasn't, but the auction reminded me that sometimes it's better to start from scratch than to try to fix what you have.

I was thinking of rebuilding some of my older sites. These sites were built while CF5 was still in development and made very little use of user-defined functions (UDFs). ColdFusion Components were only a pipe dream at that time. Given the advent of these two features, it would be more efficient for me to rebuild these sites by starting from scratch than it would be to try to continue to modify the code base as is. This month I'm going to talk about user-defined functions, and next month I'll go into ColdFusion Components.

What Is a User-Defined Function?
Before going further, you'll need to understand what a user-defined function is. In simplest terms, a UDF is a way to assign a name to a chunk of code. When you use that name, ColdFusion will know to execute its associated code. Functions can accept arguments, and they should always return a value (although it is possible to write a UDF that doesn't return anything). UDFs operate in the same manner as built-in functions, except that you must provide the code behind the function.

If you find that you are using a similar block of code many times over in your application(s), then you will probably benefit from putting that code in a function. ColdFusion provides many different string processing functions, but one I was surprised not to find is a ProperCase function. A ProperCase function is one that will capitalize the first letter of each word in a string, and lowercase all other letters. Often when displaying data, such as someone's name, you'll want to make sure that it is formatted properly before displaying it. That's when functions like ProperCase come in handy. I'm going to teach you how to create your own UDFs by creating a proper case function.

The ProperCase Algorithm
Before you can create a function you must first understand the block of code, or algorithm, that will be executed whenever the function is called. The requirements for the proper case function are:

  • Each letter that starts a word is turned capital.
  • A letter starts a word if the character before it is a space.
  • A letter starts a word if there is no character before it.
  • Each letter that is not the first letter of a word should be put into lowercase.
To force a character into capital or lowercase, we can use ColdFusion's built-in functions, UCase and LCase, respectively. Each one accepts a single parameter of the string to be moved upper or lower. There are many different ways to approach this coding. In our code we'll need to keep track of the current letter of the string and the previous letter of the string. We can compare the previous, or current letter, with a space or empty string to see if the letter should be put into upper or lower case. Another option might be to use an lcase on the whole string, and then loop through the string as a space delimited list. I am not using this method because ColdFusion ignores empty list elements, and our resulting string structure may not be preserved. See Listing 1 to see how we implement the code, as if it were in a normal CF page.

The code starts by setting the string we want to put in ProperCase. In normal circumstances, this string would be something we took out of a database or that was input by a user. Then we initialize variables for the current character, the previous character, and the result string. Then the code enters an index loop. The code loops from the first character in the string (character 1) to the last character of the string. The last character is determined by using the Len function on the string. Len is short for length, and it returns the number of characters in the string.

For each character in the string, we want to compare it with the previous character to decide if it goes into upper or lowercase. The first two lines in the loop set the previous value to the current value. This sounds strange, but it's what we want to do. The current variable still holds the same value as the most recent iteration of the loop, which means it is our previous value. Then the code updates the current value using the mid function. The mid function selects a number of characters out of the middle of the string. It accepts three values: the string to remove characters from, the first character we want to take, and the length of the resultant string we want. The code is pulling characters out of our str string. It starts at the current character of the string, which we can tell by using the counter variable. The length is 1 because we are comparing single characters.

The next part of the loop decides what to do with the current character. If the previous character is a space or an empty string and the current character is not a space or an empty string, then we move it to uppercase and append it to the result. This prevents us from putting empty spaces into uppercase. If the current character is not a space nor empty string, then it is put into lowercase. Otherwise we just append the character to the result string. After the loop there is additional code to output the original value and the proper case value.

The Tags Used to Create Functions
You don't want to have to write this chunk of code every time you need to put a string into proper case, do you? I didn't think so. Let's create a UDF based on this algorithm. There are two different ways to create UDFs in ColdFusion. The first is through the use of the cffunction, cfargument, and cfreturn tags. The second is to use CFScript. In ColdFusion 5, UDFs could only be created in CFScript, but ColdFusion MX introduced the tag-based syntax, which we're going to start with. It's also easier to understand for people who haven't been exposed to CFScript.

The cffunction tag is used to define the function. It accepts the following attributes:

  • Name: The name attribute specifies the name of the function. Function naming is similar to variable naming. The names of built-in CFML functions are not allowed. This is a required attribute.
  • Returntype: The returntype specifies the return type of the function. The valid values are Any, Array, Binary, Boolean, Date, guid, numeric, query, string, struct, uuid, variablename, void, or the name of a ColdFusion Component. The default is "Any", which means that anything can be returned from the function. This attribute is optional.
  • Roles: The roles attribute is used to specify the roles that are allowed to access this function. This refers to the roles that are set when a user logs in using the ColdFusion cfloginuser tag. It applies only inside a ColdFusion Component and doesn't apply to standalone functions (UDFs not inside a CFC). This attribute is optional.
  • Access: This attribute applies only to functions inside ColdFusion Components and specifies how the function exposes itself outside the CFC. The allowed values are: private, which means only code inside the component can execute this function; package, which means only code inside the component package can execute it; public, which means anyone can execute it; and remote which means it can be evoked remotely via Web services or Flash Remoting or a URL interface. This attribute is optional and defaults to "public".
  • Output: Specifies whether output will be displayed inside the component or not. If set to yes, then the body of the function will be treated as if it were inside a cfoutput. If set to no, then the body of the function will be treated as if it were inside a cfsilent. This attribute is optional and defaults to "yes".
  • Displayname: Displayname is an optional attribute used only for display in the metadata generated for a component. It has no effect on functionality.
  • Hint: The hint attribute is used to display comments or additional documentation in the component metadata. It has no effect on functionality and is optional.
The cfargument tag is used to define arguments that can be passed into the function. It must always be used inside a cffunction tag block body immediately following the opening cffunction tag. These are its arguments:
  • Name: The name attribute specifies the name of the argument and is required.
  • Type: The argument type is similar to the returntype of the cffunction tag. It specifies the type of value that is expected for this argument. The default is "any", which means that any valid value is acceptable. Other values are Array, Binary, Boolean, Date, guid, numeric, query, string, struct, uuid, variablename, void, or the name of a ColdFusion Component.
  • Required: This argument is either true or false, and it specifies whether the argument is required or not. If a required value is not passed to the function, then ColdFusion will throw an error. This is an optional argument and the default is false, or not required.
  • Default: The default attribute specifies the value that this argument will be given if it is not specified. This is mutually exclusive with the required attribute.
  • Displayname and Hint: The displayname and hint attributes are used strictly for metadata (documentation) purposes in components, just like these attributes are used with the cffunction name, and are not required.
The last tag that can be used in relation to functions is the cfreturn tag. The cfreturn tag doesn't have any attributes. It operates in a way similar to the cfif tag - you simply place an expression in the tag (there is no closing cfreturn tag). This expression is the return value.

Creating Your First Function
With an understanding of the tags that are used to create user-defined functions, you can now examine the ProperCase code turned into a function (see Listing 2).

The function starts with the cffunction tag. This is a fairly simple function declaration specifying only that there is no output inside the function, it will return a string, and the name of the function is ProperCase. Then one argument is defined, "str", which is the string that the function will put into proper case. The argument value passed is available in the arguments scope.

The next step in the function declares our local variables. Local variables in functions are private to the function - this means that they are protected from variables with the same name in other pages and functions and that they don't expose themselves outside of the function. Private variables are put in an unnamed scope, so you only access it by the variable name with no scope specified. Local variables must be declared at the beginning of the function immediately following any arguments. They are done using the cfset tag with the var keyword. As a best practice, be sure to var all variables used in the function that you do not want to exist outside of the function. This includes the counter variable, which we use in the loop. The current character, previous character, and result string values are all initialized.

The meat of the code remains almost identical to our initial code. In fact I copied and pasted it from the CF page inside the function page. I made one slight change, to specify the argument scope whenever the str variable is referenced. The last line of the function uses the cfreturn tag to return the result string. If you test the code you'll find it runs no differently than the brute force code approach, but is now easily executed from any part of my files - reusability achieved!

Conclusion
The most common way to call a user-defined function is to do so the same way as a built-in function. You can call it within any ColdFusion expression. There is an alternate way, including using the cfinvoke tag, if the function is part of a ColdFusion Component. Additionally, there is a CFScript syntax for writing your own functions. You can read more about that at http://livedocs.macromedia.com/coldfusion/6.1/htmldocs/udfs5.htm. Before you go about writing your own function, you may want to check to see if it exists at the common function library project, found at www.cflib.org. cflib is a great learning and development resource and you'll find many functions to do many different things. Next month I'm going to take a look at ColdFusion Components. While functions are great for modularizing functionality, components allow you to modularize both data and functionality.

More Stories By Jeffry Houser

Jeffry is a technical entrepreneur with over 10 years of making the web work for you. Lately Jeffry has been cooped up in his cave building the first in a line of easy to use interface components for Flex Developers at www.flextras.com . He has a Computer Science degree from the days before business met the Internet and owns DotComIt, an Adobe Solutions Partner specializing in Rich Internet Applications. Jeffry is an Adobe Community Expert and produces The Flex Show, a podcast that includes expert interviews and screencast tutorials. Jeffry is also co-manager of the Hartford CT Adobe User Group, author of three ColdFusion books and over 30 articles, and has spoken at various events all over the US. In his spare time he is a musician, old school adventure game aficionado, and recording engineer. He also owns a Wii. You can read his blog at www.jeffryhouser.com, check out his podcast at www.theflexshow.com or check out his company at www.dot-com-it.com.

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


IoT & Smart Cities Stories
Every organization is facing their own Digital Transformation as they attempt to stay ahead of the competition, or worse, just keep up. Each new opportunity, whether embracing machine learning, IoT, or a cloud migration, seems to bring new development, deployment, and management models. The results are more diverse and federated computing models than any time in our history.
At CloudEXPO Silicon Valley, June 24-26, 2019, Digital Transformation (DX) is a major focus with expanded DevOpsSUMMIT and FinTechEXPO programs within the DXWorldEXPO agenda. Successful transformation requires a laser focus on being data-driven and on using all the tools available that enable transformation if they plan to survive over the long term. A total of 88% of Fortune 500 companies from a generation ago are now out of business. Only 12% still survive. Similar percentages are found throug...
Japan DX Pavilion at @CloudEXPO Silicon Valley
In his general session at 19th Cloud Expo, Manish Dixit, VP of Product and Engineering at Dice, discussed how Dice leverages data insights and tools to help both tech professionals and recruiters better understand how skills relate to each other and which skills are in high demand using interactive visualizations and salary indicator tools to maximize earning potential. Manish Dixit is VP of Product and Engineering at Dice. As the leader of the Product, Engineering and Data Sciences team at D...
The graph represents a network of 1,329 Twitter users whose recent tweets contained "#DevOps", or who were replied to or mentioned in those tweets, taken from a data set limited to a maximum of 18,000 tweets. The network was obtained from Twitter on Thursday, 10 January 2019 at 23:50 UTC. The tweets in the network were tweeted over the 7-hour, 6-minute period from Thursday, 10 January 2019 at 16:29 UTC to Thursday, 10 January 2019 at 23:36 UTC. Additional tweets that were mentioned in this...
At CloudEXPO Silicon Valley, June 24-26, 2019, Digital Transformation (DX) is a major focus with expanded DevOpsSUMMIT and FinTechEXPO programs within the DXWorldEXPO agenda. Successful transformation requires a laser focus on being data-driven and on using all the tools available that enable transformation if they plan to survive over the long term. A total of 88% of Fortune 500 companies from a generation ago are now out of business. Only 12% still survive. Similar percentages are found throug...
Where many organizations get into trouble, however, is that they try to have a broad and deep knowledge in each of these areas. This is a huge blow to an organization's productivity. By automating or outsourcing some of these pieces, such as databases, infrastructure, and networks, your team can instead focus on development, testing, and deployment. Further, organizations that focus their attention on these areas can eventually move to a test-driven development structure that condenses several l...
The term "digital transformation" (DX) is being used by everyone for just about any company initiative that involves technology, the web, ecommerce, software, or even customer experience. While the term has certainly turned into a buzzword with a lot of hype, the transition to a more connected, digital world is real and comes with real challenges. In his opening keynote, Four Essentials To Become DX Hero Status Now, Jonathan Hoppe, Co-Founder and CTO of Total Uptime Technologies, shared that ...
Over the course of two days, in addition to insightful conversations and presentations delving into the industry's current pressing challenges, there was considerable buzz about digital transformation and how it is enabling global enterprises to accelerate business growth. Blockchain has been a term that people hear but don't quite understand. The most common myths about blockchain include the assumption that it is private, or that there is only one blockchain, and the idea that blockchain is...
Never mind that we might not know what the future holds for cryptocurrencies and how much values will fluctuate or even how the process of mining a coin could cost as much as the value of the coin itself - cryptocurrency mining is a hot industry and shows no signs of slowing down. However, energy consumption to mine cryptocurrency is one of the biggest issues facing this industry. Burning huge amounts of electricity isn't incidental to cryptocurrency, it's basically embedded in the core of "mini...