How to call a function dynamically that is part of an instantiated cfc, without using Evaluate()?

StackOverflow https://stackoverflow.com/questions/84463

  •  01-07-2019
  •  | 
  •  

Question

For example I want to be able to programatically hit a line of code like the following where the function name is dynamically assigned without using Evaluate(). The code below of course doesn't work but represents what I would like to do.

application.obj[funcName](argumentCollection=params)

The only way I can find to call a function dynamically is by using cfinvoke, but as far as I can tell that instantiates the related cfc/function on the fly and can't use a previously instantiated cfc.

Thanks

Was it helpful?

Solution

According to the docs, you can do something like this:

<!--- Create the component instance. --->
<cfobject component="tellTime2" name="tellTimeObj">
<!--- Invoke the methods. --->
<cfinvoke component="#tellTimeObj#" method="getLocalTime" returnvariable="localTime">
<cfinvoke component="#tellTimeObj#" method="getUTCTime" returnvariable="UTCTime">

You should be able to simply call it with method="#myMethod#" to dynamically call a particular function.

OTHER TIPS

You can use cfinvoke. You don't have to specify a component.

<cfinvoke method="application.#funcName#" argumentCollection="#params#">

You can also do something very similar, to the way you wanted to use it. You can access the method within the object using the syntax you used, you just can't call it at the same time. However, if you assign it to a temp variable, you can then call it

<!--- get the component (has methods 'sayHi' and a method 'sayHello') --->
<cfset myObj = createObject("component", "test_object")>

<!--- set the function that we want dynamically then call it (it's a two step process) --->
<cfset func = "sayHi">
<cfset funcInstance = myObj[func]>
<cfoutput>#funcInstance("Dave")#</cfoutput>

<cfset func = "sayHello">
<cfset funcInstance = myObj[func]>
<cfoutput>#funcInstance("Dave")#</cfoutput>

In CFML, functions are first-class members of the language. This allows us to pass them around like a variable. In the following example I will copy the function named 'foobar' and rename it "$fn" within the same object. Then, we can simply call $fn().

funcName = 'foobar';    
application.obj.$fn = application.obj[funcName];
application.obj.$fn(argumentCollection=arguments);

The context of the function is important, especially if it references any values in the 'variables' or 'this' scope of the object. Note: this is not thread safe for CFC instances in shared scopes!

The fastest method is to use Ben Doom's recommendation. I just wanted to be thorough.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top