Calling functions with a dynamic name
posted under category: ColdFusion on May 28, 2009 by Nathan
For a while now, the CF community has been stumbling around the concept of calling a dynamic function. Well, as it turns out, ColdFusion is more functional that it may seem on the surface. Let’s have some fun with what, at first, seems like a difficult problem.
Let’s say we have a method that receives the name of another method as an argument: myStaticFunction("myDynamicFunction")
. Now what? First, here’s the methods (I haven’t checked any of this, so let’s call it pseudo-code.
function myDynamicFunction(){return true;}
function myStaticFunction(methodName) {
methodName(); // fails for calling a string like a function
variables[methodName](); // fails for a syntax error - []() = bad cfml!
// umm, now what?
}
So here we are in the same old spot. First, the old school method, the one easily turned to in time of need, the cfinvoke tag. Personally, I dislike the cfinvoke tag. It seems to take me out of my flow. It ruins my mojo. It’s like longhand syntax for CF - it’s somewhat of an oxymoron. Nevertheless, here’s what you would do:
<!--- First, note that we have to rewrite it in tags. Not awful, but I dislike the switch. --->
<cffunction name="myStaticFunction">
<cfargument name="methodName" />
<cfset var methodResult = "" />
<cfinvoke method="#methodName#" returnvariable="methodResult" />
<cfreturn methodResult />
</cffunction>
This works, but there’s got to be a better way! There has to be a less cheap way, something without all the #'s and stuff. And there is:
// back to cfscript, yay!
function myStaticFunction(methodName) {
var method = variables[methodName];
return method();
}
That’s much more like it! Of course this assumes we’re in a cfc or something, where the method is in the variables scope. Now, what other magical things can we do?
Well, I wasn’t going to share this one until the next entry, but since you’re talking me into it, here it is with onMissingMethod, dynamically calling a method with dynamic arguments. This onMissingMethod attempts to call a getter when you just call the property - in other words, user.name()
will be automatically translated into user.getName()
, to give you a nice jQuery type of syntax:
function onMissingMethod(missingMethodName, missingMethodArguments) {
var f = 0;
if (structKeyExists(variables, "get" & arguments.missingMethodName)) {
f = variables["get" & arguments.missingMethodName];
f(argumentCollection=arguments.missingMethodArguments);
} else {
// choke!
}
}