Title: Building User Defined Functions (UDF)
1Building User Defined Functions (UDF)
Speaker Jo Belyea-Doerrman jobdoer_at_teratech.c
om TeraTech Consultant
2Speaker Information
- Who am I?
- ColdFusion Developer
- ColdFusion Developer since 1997
- Teach one-on-one and custom classes for TeraTech
3This Session
- This session I will
- introduce you to the brave new world of
user-defined functions (UDFs) - demonstrate two ways to create your own
functions - show you where to get UDFs others have written.
4Extend CFML
- One of the advantages of CF is that it is
extensible. - CFML can be easily extended beyond the tags and
functions that are built-in.
54 ways to extend Cold Fusion
- User-Defined Functions
- Custom Tags
- ColdFusion Components (CFCs)
- CFX Tags
- This session focuses on UDFs.
6What are UDFs?
Simply put, UDFs are functions that you create
and/or share. If you feel that some function is
missing from CF make it yourself!
7User-Defined Functions (UDFs)
- Think of them as little engines on an assembly
line - Accepts input runs it through the function and
creates some kind of corresponding output - Now can be built with CFFUNCTION, CFARGUMENT
CFRETURN tags.
Ucase()function
8Why use UDFs instead of Custom Tags?
- Only UDFs provide the convenience of return
values. - Custom tags can create values (as
Caller.VariableName) that are accessible to the
calling template after their execution, but with
UDFs the return value is the primary goal of the
function.
9Why use UDFs? Cont.
- Performance may be worth some consideration when
deciding to use UDFs or custom tags. - If a function is to be performed multiple times
within one template, a UDF would most likely
out-perform the custom tag. This is due to the
fact that processing does not have to leave the
template every time a UDF is executed. With the
custom tag, it goes out to the tag itself each
time processing of the task is required.
10Whats new?
- Completely overhauled in CFMX.
- Can be written with Cold Fusion tags or using
CFSCRIPT - No longer have to write UDFs with CFSCRIPT
strongly recommend using ltCFFUNCTIONgt rather than
this method - Note If you are writing UDFs in CF5 you must
still write them in CFSCRIPT
11Basic steps to a UDF with tags
- To create a user-defined function you will need
to four basic steps that use the following tags - CFFUNCTION
- CFARGUMENT
- CFRETURN
12Step 1
- Start with a pair of ltCFFUNCTIONgt tags. All the
code you need to make the function do its work
goes in between these tags.
13Step 2
- ltCFARGUMENTgt Add each argument your function
will be using for input. Can make required or
optional.
14Step 3
- Add any CFML code that is needed to make your
function work. Can use whatever tags and
functions you want.
15Step 4
- The last step uses the ltCFRETURNgt tag. It
specifies what your functions output should be.
16Building Your First UDF
- You may find yourself wanting a function that
pulls an employees e-mail address from the db. - You could use this
- ltCFOUTPUTgtgetEmployeeEmail(8)
- lt/CFOUTPUTgt
- You could create it using the old ltCFQUERYgt
taghowever, you can also turn this into a
function very easily!
17Lets look at some code!
- Well call the UDF GetEmployeeEmail()
18GetEmployeeEmail()
- ltCFFUNCTION nameGetEmployeeEmailgt
- ltCFARGUMENT NAMEEmployeeID TYPENumeric
REQUIREDYesgt - lt!---Get the Employees email---gt
- ltCFQUERY NamegetEmployee DATASOURCEdatasourc
e - CACHEDWITHINCreateTimespan(0,1,0,0)gt
- SELECT EmployeeEmail FROM Employees
- WHERE ARGUMENTS.EmployeeID
- lt/CFQUERYgt
- lt!--- Return the employees email ---gt
- ltCFRETURN getEmployee.EmployeeEmailgt
- lt/CFFUNCTIONgt
19Using the Function
- Once written, this can be used like any other
function. - When CF sees the function -- It runs the code
between the corresponding ltCFFUNCTIONgt tags. - Arguments can be
- Static
- ltCFOUTPUTgtGetEmployeeEmail(8)lt/CFOUTPUTgt
- Dynamic
- ltCFOUTPUTgtGetEmployeeEmail(FORM.ShowEmployeeID)
- lt/CFOUTPUTgt
- Used within ltCFSETgt
- ltCFSET myEmployeeLowerCase Lcase(GetEmployeeEma
il(FORM.ShowEmployeeID))gt
20How do the tags work?
21ltCFFUNCTIONgt
- NAME You will call the function using the name
provided here. Must be a valid CFML identifier. - RETURNTYPE Optional. Type of info the function
will return. String, numeric, date and so on.
Use to make functions more self-documenting.
22ltCFARGUMENTgt
- NAME The name of the argument.
- TYPE Optional. The data type that should be
supplied to the argument. If you supply a TYPE,
CF will display an error if someone tries to use
the function with the wrong kind of input. - REQUIRED Optional. Default is No.
- DEFAULT Optional. For optional arguments
(REQUIRED No), the value of the argument when
the value is not passed in.
23Required Arguments
- ltCFARGUMENT
- REQUIRED Yesgt
- Argument must be provided the function is
actually used. - If the argument is not provided at runtime, CF
will display an error message.
24Optional Arguments
- If REQUIREDno and a default has been specified
then the function can be called either with or
without the argument at runtime. - If the value IS provided, the value will be what
is presented in the ARGUMENTS scope. - If not, the DEFAULT value will be used
- If REQUIREDno and a default has NOT been
specified then the function still optional. You
can use the IsDefined() function to determine
whether the argument is provided at runtime.
25ltCFRETURNgt
- Return value can be any expression
- Has no attributes per se. Instead, you determine
whatever string, number, date, variable or
expression you want directly returned within the
ltCFRETURN gt tag. - Examples
- ltCFRETURN agt
- ltCFRETURN TimeFormat(Now())gt
- ltCFRETURN The current time is
TimeFormat(Now())gt
26Dont show variables
- Most times you dont want variables to be visible
to pages that use the function - You need to tell CF that a particular variable
should only be visible within the context of the
ltCFFUNCTIONgt block. - Dont want function to have side effects.
- Should not have to worry about its overwriting
any variables already defined - Called a Local Variable
27Using Local Variables
- ltCFSET var myLocalVariable Hellogt
- The var keyword tells CF that the variable should
cease to exist when ltCFFUNCTIONgt block ends.
28Local Variable Rules
- Can declare as many as you want. Use separate
ltCFSETgt for each, using the var keyword each
time. - ltCFSETgt must be at the very top of ltCFFUNCTIONgt
block right after the ltCFARGUMENTgt tags.
29Local Variable Rules cont.
- Can not declare without a value. There must be
an sign with an initial value. Can change
later in the functions code.
30Where to Save Your UDFs
- You can Create and Use UDF in the same file
- or
- Save UDFs in Separate Files for easy reuse
- Reusing code saves time and effort
- ltCFINCLUDEgt function code
- If you want function available at the application
level, ltCFINCLUDEgt function code in
Application.cfm
31Creating Libraries of Related UDFs
- No specific rules what kinds of UDFs can be
collected into a library. - Makes sense to group your UDFs into different
files according to some kind of common concept - UDFs can call other UDFs in the same file.
- They can even call functions in other files as
long as the ltCFINCLUDEgt tag has been used to
include the other files
32Uses for UDFs
33Adding Tags to CFSCRIPT
- Another good use is when wanting to do something
only supported by tags within a CFSCRIPT block - For instance, may want to do a CFDUMP in a script
- Cant use that tag in CFSCRIPT
- But can create UDF to do it and call that from
script
34CFFUNCTION_dumpudf code
- lt!--- cffunction_dumpudf.cfm ---gt
- ltcffunction name"dump"gt ltcfargument
name"var"gt ltcfargument name"label"
required"no" default""gt ltcfoutputgtarguments.la
bellt/cfoutputgt ltcfdump var"arguments.var"gt lt
brgtlt/cffunctiongt
35Adding Tags to CFSCRIPT
- You can now call it just like any other UDF
- In this example, calling inside CFSCRIPT
- Not a requirement. Can call outside CFSCRIPT too
36Calling
- lt!--- other\call_dumpudf.cfm ---gt
- ltcfinclude template"cffunction_dumpudf.cfm"gt
- ltcfscriptgt
- // while creating code in CFSCRIPT you often
want to dump something - // server scope is something we can now dump in
CFMX - dump(var"server")
- // or simply
- dump(server)
- lt/cfscriptgt
37Benefits Over CFSCRIPT UDFs
- Besides ability to use tags within UDF
- More important point may be ability to use
CFARGUMENT, and ReturnType on CFFUNCTION - These give greater control over data types over
data coming into and going out of UDF - and required/optional support for arguments
coming in
38Benefits Over CFSCRIPT UDFs
- Also, can use the ROLES attribute on CFFUNCTION
to limit use by authorized users (see
CFLOGINUSER) - Also, in script, there is no equivalent to
CFTHROW - Still, the choice will more often be one of
programming style - Each approach has its place
39UDF written with CFSCRIPT
- function TempConvert(ATemp, ItsScale)
- if (not IsNumeric(ATemp)) return "NAN"
- if (UCase(ItsScale) eq "F")
- // temp given in Fahrenheit. Convert to Celsius
degs (ATemp - 32.0) ( /9.0) - else if
- (UCase(ItsScale) eq "C")
- // temp given in Celsius. Convert to Fahrenheit
degs (ATemp 9.0/5.0) 32 - else
- degs "Not a valid scale"
-
- return degs 50 degrees Fahrenheit is
TempConvert("50","F") degrees Celsius.
40Calling the UDF
- Call the UDF by using the following
- 50 degrees Fahrenheit is TempConvert("50","F")
degrees Celsius.
41What does it do?
- Prints "50 degrees Fahrenheit is 10 degrees
Celsius."
42How does it work?
- Two arguments are passed to the function a
temperature and the scale that it is in. - The temperature is checked to make sure it's a
number (the value "NAN" is returned and
processing ends if it is not). - Then the calculation is processed based on the
scale being "F" or "C." - If the scale given is neither "F" nor "C," the
message "Not a valid scale" is returned.
43Rules for function definitions
- The following rules apply to functions that you
define using CFScript or the CFFunction tag - The function name must be unique. It must be
different from any existing variable, UDF, or
built-in function name. - The function name must not start with the letters
cf in any form. (For example, CF_MyFunction
cfmyFunction, and cfxMyFunction are not valid UDF
names.)
44Rules cont.
- You cannot redefine or overload a function. If a
function definition is active, ColdFusion
generates an error if you define a second
function with the same name. - You cannot nest function definitions that is,
you cannot define one function inside another
function definition.
45Rules cont.
- The function can be recursive, that is, the
function definition body can call the function. - The function does not have to return a value
46Define a function in the following places
- On the page where it is called.
- You can even define it below the place on the
page where it is called, but this poor coding
practice can result in confusing code.
47Define a function in the following places
- On any page that puts the function name in a
scope common with the page on which you call the
function.
48Define a function in the following places
- On a page that you include using a cfinclude tag.
- The cfinclude tag must be executed before the
function gets called. For example, you can define
all your application's functions on a single page
and place a cfinclude tag at the top of pages
that use the functions.
49Define a function in the following places
- Application.cfm page.
- Consider the following techniques for making your
functions available to your ColdFusion pages on
the following pages.
50Using Application.cfm and function include files
- If you consistently call a small number of UDFs,
consider putting their definitions on the
Application.cfm page.
51Using Application.cfm and function include files
cont.
- If you call UDFs in only a few of your
application pages, do not include their
definitions in Application.cfm.
52Using Application.cfm and function include files
cont.
- If you use many UDFs, put their definitions on
one or more ColdFusion pages that contain only
UDFs. You can include the UDF definition page in
any page that calls the UDFs.
53Specifying the scope of a function
- User-defined function names are essentially
ColdFusion variables. ColdFusion variables are
names for data. Function names are names
(references) for segments of CFML code.
Therefore, like variables, functions belong to
scopes.
54Do not use the following as names of CFCs or UDFs
equals getClass getMetadata getPagePath getSuperScope invoke hashCode notify notifyAll setSuperScope toString wait
55Where can I find UDFs?
- www.cflib.com
- www.macromedia.com
56Ideas from the audience
- Any thoughts on how you could use UDFs in your
programming? - Share your thoughts
57Where can I find out more information?
- http//livedocs.macromedia.com/coldfusion/6.1/html
docs/udfs.htm - http//www.macromedia.com/devnet/server_archive/ar
ticles/user_defined_functions.html - http//www.macromedia.com/devnet/mx/coldfusion/art
icles/ud_functions.html - http//www.cflib.org/resources.cfm
- Macromedia Coldfusion MX Web Application
Construction Kit Fifth Edition Chapter 19
58Conclusion
- UDFs are easy to write.
- Now go out and write your own UDFs!