The Dopefly Tech Blog

« The Dopefly Tech Blog Main page

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!
    }
}
Nathan is a software developer at The Boeing Company in Charleston, SC. He is essentially a big programming nerd. Really, you could say that makes him a nerd among nerds. Aside from making software for the web, he plays with tech toys and likes to think about programming's big picture while speaking at conferences and generally impressing people with massive nerdiness and straight-faced sarcastic humor. Nathan got his programming start writing batch files in DOS. It should go without saying, but these thought and opinions have nothing to do with Boeing in any way.
This blog is also available as an RSS 2.0 feed. Click your heels together and click here to contact Nathan.