I'm writing a function that loops through some info on a registration page. Within the loop I'm trying to call functions based on an array. What I'm having problems with is actually calling the functions properly, because I'm trying to incorporate a variable as part of the function name.
Here's my code:
<cfscript>
fields = arraynew(1);
fields[1] = 'r_email';
fields[2] = 'r_uname';
fields[3] = 'r_pass';
for(i = 1; i lte arraylen(fields); i = i + 1)
{
func = fields[i].split('r_');
func = 'validate_#func[2]#(#fields[i]#)';
}
</cfscript>
So, I have three functions: validate_email, validate_uname, validate_pass. If I throw in a writeoutput(), and attempt to output the results of the function, they do not work.
Here's that code:
<cfscript>
fields = arraynew(1);
fields[1] = 'r_email';
fields[2] = 'r_uname';
fields[3] = 'r_pass';
for(i = 1; i lte arraylen(fields); i = i + 1)
{
func = fields[i].split('r_');
func = 'validate_#func[2]#(#fields[i]#)';
writeoutput('#func#');
}
</cfscript>
Now, I understand that when you're using writeoutput(), and you're calling a function, you need the hash symbol on either end. So, let's say I write it like this:
writeoutput('#validate_#func[2]#(#fields[i]#)#');
It won't work, because the second hash symbol cancels out the function call. This is how the function should ultimately look (email example):
writeoutput('#validate_email('[email protected]')#');
How can I replace 'email' (#validate_email...) with the proper variable name, and still have the function work? I hope I've made this understandable!
Variables and functions have separate name spaces, which means a variable and a function can have the same name, such as value and value(), and Mata will not confuse them.
You can see the current (JVM) type of a variable by doing <cfdump var=#getMetadata(var)# /> or simply by accessing getMetadata(var). getName() .
Use an Array of Variables The simplest JavaScript method to create the dynamic variables is to create an array. In JavaScript, we can define the dynamic array without defining its length and use it as Map. We can map the value with the key using an array and also access the value using a key.
You create most ColdFusion variables by assigning them values. (You must use the ArrayNew function to create arrays.) Most commonly, you create variables by using the cfset tag. You can also use the cfparam tag, and assignment statements in CFScript.
Functions are variables too, so in the same way you can use bracket notation for arrays, structs, and scopes, you can use this to access dynamic variable names (and thus dynamic function names)
For example:
<cfloop index="Field" list="email,uname,pass">
<cfset Result = Variables['validate_'&Field]( Variables['r_'&Field] ) />
...
</cfloop>
Well... not quite. Due to a bug in Adobe ColdFusion, that doesn't work like that (though it does in other CFML engines, like Railo), and you have to split it into two lines, like this:
<cfloop index="Field" list="email,uname,pass">
<cfset TmpFunc = Variables['validate_'&Field] />
<cfset Result = TmpFunc( Variables['r_'&Field] ) />
...
</cfloop>
(This assumes both function and fields are in the variables
scope, if they're not you need to refer to whichever scope they're in.)
This method does have an issue if the function was in an object with state, it loses reference to those variables.
On CF10, there is the invoke
function. Earlier versions of CF need to use the cfinvoke
tag.
(As a side note, CF10 did add the inverse ability of referencing function results with bracket notation, i.e. doSomething()[key]
which comes in useful at times.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With