How Do I Get A Pointer To A Built In ColdFusion Method?

Posted March 1, 2007 at 2:18 PM by Ben Nadel

Tags: ColdFusion

Does anyone know how to get a pointer to a built in ColdFusion method? I want to do something along the lines of:

  • <!--- Check for regular expression search. --->
  • <cfif ARGUMENTS.IsRegex>
  •  
  • <!--- Get regex find. --->
  • <cfset Method = REFindNoCase />
  •  
  • <cfelse>
  •  
  • <!--- Get standard find. --->
  • <cfset Method = FindNoCase />
  •  
  • </cfif>
  •  
  • <!--- Use method pointer. --->
  • <cfif Method( "foo", "I like foo bar" )>
  • <!--- Code here. --->
  • </cfif>

The problem with this is that it throws an undefined variable error (FindNoCase). Now, I know the idea is sound as I have done it with user defined methods. But those methods are all scopes in some way and are very easy to reference. Built in ColdFusion methods are proving quite hard to find!

I tried all the different scopes and notations (array and structure):

  • <cftry>
  • <cfdump var="#FindNoCase#" />
  • <cfcatch>
  • "FindNoCase" failed.<br />
  • </cfcatch>
  • </cftry>
  •  
  • <cftry>
  • <cfdump var="#VARIABLES.FindNoCase#" />
  • <cfcatch>
  • "VARIABLES.FindNoCase" failed.<br />
  • </cfcatch>
  • </cftry>
  •  
  • <cftry>
  • <cfdump var="#VARIABLES[ 'FindNoCase' ]#" />
  • <cfcatch>
  • "VARIABLES[ 'FindNoCase' ]" failed.<br />
  • </cfcatch>
  • </cftry>
  •  
  • <cftry>
  • <cfdump var="#APPLICATION.FindNoCase#" />
  • <cfcatch>
  • "APPLICATION.FindNoCase" failed.<br />
  • </cfcatch>
  • </cftry>
  •  
  • <cftry>
  • <cfdump var="#APPLICATION[ 'FindNoCase' ]#" />
  • <cfcatch>
  • "APPLICATION[ 'FindNoCase' ]" failed.<br />
  • </cfcatch>
  • </cftry>
  •  
  • <cftry>
  • <cfdump var="#REQUEST.FindNoCase#" />
  • <cfcatch>
  • "REQUEST.FindNoCase" failed.<br />
  • </cfcatch>
  • </cftry>
  •  
  • <cftry>
  • <cfdump var="#REQUEST[ 'FindNoCase' ]#" />
  • <cfcatch>
  • "REQUEST[ 'FindNoCase' ]" failed.<br />
  • </cfcatch>
  • </cftry>

This gives me the following output:

"FindNoCase" failed.
"VARIABLES.FindNoCase" failed.
"VARIABLES[ 'FindNoCase' ]" failed.
"APPLICATION.FindNoCase" failed.
"APPLICATION[ 'FindNoCase' ]" failed.
"REQUEST.FindNoCase" failed.
"REQUEST[ 'FindNoCase' ]" failed.

Anyone know where I can find these method pointers?




Reader Comments

Mar 1, 2007 at 2:38 PM // reply »
79 Comments

You might just wrap them, if nothing else comes up.


Mar 1, 2007 at 2:56 PM // reply »
35 Comments

Try this.

if StructKeyExists( component, methodname )


Mar 1, 2007 at 3:01 PM // reply »
11,241 Comments

@Sam,

Yeah, I could work something out. For my directory search UDF, I ended up just putting both test cases into a single CFIF conditional.

@Dan,

The problem is that built in methods are not part of any component that I can check.


Mar 1, 2007 at 4:36 PM // reply »
6 Comments

How about an evaluate? This works:

<cfset Method = "FindNoCase" />
<cfset x = evaluate("#Method#('foo', 'I like foo bar')") />
<cfoutput>#x#</cfoutput>


Mar 1, 2007 at 4:47 PM // reply »
13 Comments

My java knowledge is almost non-existent. This may not help at all, but I figure it never hurts to share information.

I found a post about running your own Java libraries with coldfusion. In one of the comments, Mark mentions that his code supports access to built in classes and libraries, although I didn't see an example of that.

http://www.compoundtheory.com/?action=displayPost&ID=114

I played around with some of the code on the page. The code below displays the method names of something. Number 269 is FindNoCase with two parameters. Number 270 is FindNoCase with three parameters.

<!--- Do something? --->
<cfset cfClassLoader = getClass()>

<!--- Get the methods --->
<cfset var_getMethods = cfClassLoader.getMethods()>

<!--- Loop through the methods and display their names --->
<cfloop from="1" to="#arrayLen(var_getMethods)#" index="currentMethodIndex">
<cfoutput>
#currentMethodIndex# - #var_getMethods[currentMethodIndex].getName()#<br />
</cfoutput>
</cfloop>

I tried playing around with CFDUMP to equate a variable to a method but didn't have much success. Again, my Java knowledge is very limited.


Mar 2, 2007 at 7:33 AM // reply »
10 Comments

Although I think this is interesting I think maybe WHY!? is even more interesting.

I can't think of a case where this would be particularly useful? Maybe you could give a fuller example of what you're trying to do?

D


Mar 2, 2007 at 7:39 AM // reply »
11,241 Comments

@David,

Look at the example I gave. It checks a flag for regular expression usage and then uses either a REFind() or Find() method. This is actually the situation where this came up. REFind() and Find() have the same arguments, it should be very easy to swap them out.

Now, imagine if that was part of some HUGE CFIF statement. I wouldn't want to duplicate the logic depending on a flag.

Plus, this is mad elegant and sexy.


Mar 2, 2007 at 7:48 AM // reply »
10 Comments

Hi Ben,

Yes I get what you're trying to do but probably just disgaree on it's elegance factor.... (definitely on the mad factor tho! :p)

This situation sounds like it would fit the proxy(?) pattern nicely:

cffunction myFind(regEx, str, sub, ....)
cfif regEx
cfreturn refind()....
cfelse
cfreturn find()...
/cfif
/cffunction

Wouldn't that be a more elegant solution?

D


Mar 2, 2007 at 7:53 AM // reply »
11,241 Comments

@Dave,

I guess it's just a matter of opinion. Your solution, which is good, requires another UDF to be defined. Nothing wrong with that. But I just feel for something that should be really simple, having a proxy method ties the given UDF to more parts of an application that it needs to be.

But, in the end, your suggestion might just be the best idea.


Mar 2, 2007 at 7:59 AM // reply »
79 Comments

David,
In that situation, I don't think there is much difference between

if (condition)
return something
else
return something else

In fact, a lot of people are big fans of having a single point of return in a function, as it can make it easier to follow knowing there is only one place the function returns control to its calling code.

From that view, it would certainly be worse that doing something like

if(condition)
result=something
else
result=something else

return result


Mar 2, 2007 at 8:00 AM // reply »
79 Comments

With all that said though, I think I'd simply use the REFind if there was a chance of using regular expressions. After all, it's still a regular expression even if you don't use any special characters.


Mar 2, 2007 at 8:00 AM // reply »
10 Comments

Ben,

I'm interested to know what other languges you've done this in?

D


Mar 2, 2007 at 9:28 AM // reply »
10 Comments

Sam

I agree on the single return point. I was kinda just illustrating the point of abstracting the functionality into another function.

I agree on the just use reFind() although I imagine Ben was aware of that too. I think the question was more about can you do it the pointer way and/or is there a more elegant way (ans: probably not).

Without doing any tests I would also think that always using reFind() is faster than a function because it'd be another class to deal with.

D


Mar 2, 2007 at 11:07 AM // reply »
11,241 Comments

The problem with always using REFind() is that the string you are searching for might have "reg-ex" specific characters, so unless you want to escape all characters in the reg-ex substring, then no go.


Mar 7, 2007 at 5:42 PM // reply »
13 Comments

Ben,

Although I am not sure but this method could help you locating builtin functions

getFunctionList().

Thanks


Mar 9, 2007 at 4:22 PM // reply »
11,241 Comments

@Qasim,

Thanks for the suggestion. I talked to Michael Dinowitz yesterday at CFUNITED Express NYC and he said that this cannot be done (getting method pointers) for built in methods because the methods (as opposed to UDFs) are just wrappers for the Java methods. They are not really first class objects like UDFs.


Mar 18, 2007 at 4:43 PM // reply »
6 Comments

Sorry not to be in English.
But my two cents.
http://pcsilva.blogspot.com/2007/03/onde-est-funo-mais-uma-que-compartilho.html


Mar 19, 2007 at 7:30 AM // reply »
11,241 Comments

@Pedro,

That looks very interesting. I have never invoked a method indirectly like that. I will play around.


Mar 20, 2007 at 6:10 PM // reply »
6 Comments

Ben,
I tried to work with the functions undocumented _invoke and _invokeUDF, but did not discover which the first parameter.

<cfoutput>#_invoke()#</cfoutput>
<cfoutput>#_invokeUDF()#</cfoutput>

Regards


Mar 20, 2007 at 6:20 PM // reply »
11,241 Comments

Hmm, I have never seen those methods, hidden or otherwise. I just tried to do a GetMetaData() on them and got undefined errors.


Mar 20, 2007 at 6:40 PM // reply »
6 Comments

See Ben,
<cfdump var="#getpagecontext().getpage()#">

It looks for the methods initiated for _, you will see some (undocumented)

_invoke(java.lang.Object, java.lang.String, java.lang.Object[]):java.lang.Object

_invoke(java.lang.Object, java.lang.String, java.util.Map):java.lang.Object

_invokeUDF(java.lang.Object, java.lang.String, coldfusion.runtime.CFPage, java.util.Map):java.lang.Object

_invokeUDF(java.lang.Object, java.lang.String, coldfusion.runtime.CFPage, java.lang.Object[]):java.lang.Object


Mar 20, 2007 at 8:04 PM // reply »
11,241 Comments

Oh, I see. Yeah, those are some tricky methods. I think that is part of what the JavaProxy thing does - it figures out how to invoke those between CF and Java. I have heard that no one can figure out how to call the Invoke methods directly.


Mar 20, 2007 at 8:25 PM // reply »
6 Comments

I believe that they can yes, the classes are different.
coldfusion.runtime.CfJspPage._invoke(...)
coldfusion.runtime.TemplateProxyFactory.resolveName()
http://www.mxstudio.com.br/views.tutorial.php?act=view&cid=7&aid=699


Mar 22, 2007 at 1:26 AM // reply »
6 Comments

It had reason how much to the direct access.

it does not work.
<cfscript>
pageContext=GetPageContext();
Object=pageContext.getClass().forName('coldfusion.runtime.TemplateProxyFactory').newInstance().resolveName('POIUtility', pageContext);

arg = ArrayNew(1);
Invoke = _invoke(Object,JavaCast('string','GetNewSheetStruct'),arg);
</cfscript>

it works

<cfscript>
pageContext=GetPageContext();
Object=pageContext.getClass().forName('coldfusion.runtime.TemplateProxyFactory').newInstance().resolveName('POIUtility', pageContext);

page = pageContext.getPage();
arg = ArrayNew(1);
Invoke = page._invoke(Object,JavaCast('string','GetNewSheetStruct'),arg);
</cfscript>


Mar 22, 2007 at 7:25 AM // reply »
11,241 Comments

Hmmm, very interesting. I will have to study this.



Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 22, 2013 at 5:35 PM
Script Tags, jQuery, And Html(), Text() And Contents()
This is still an issue 2 years later. jQuery is supposed to remediate these cross browser issues, no? I have been unable to find any statement from the jQuery team calling this behavior "by de ... read »
May 22, 2013 at 12:44 PM
Ask Ben: Query Loop Inside CFScript Tags
In cf10, if you call a function that has: local.result = {}; local.result.msg = ""; local.svc = new query(); local.svc.setSQL("SELECT * FROM..."); local.obj = local.svc.exe ... read »
May 22, 2013 at 12:29 PM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Ben: What version of Java are you using? Also, did you test users.id to see what Java reports as the data type? I wonder if it's not a Java primitive data type, but getting returned as something ... read »
May 22, 2013 at 11:47 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Dana, Awesome - so it looks like this bug was fixed in ColdFusion 10. Thanks so much for double-checking that. ... read »
May 22, 2013 at 11:37 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
When I c&p and run on cf10, I get: Selected User IDs: 1,4 User 1 selected: YES - YES User 2 selected: NO - NO User 3 selected: NO - NO User 4 selected: YES - YES User 5 selected: NO - ... read »
May 22, 2013 at 11:27 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Tom, Good thought, but no dice. Both of these still exhibit the same behavior: users.id[ users.currentRow ] users[ "id" ][ users.currentRow ] It's just something whacky happening with ... read »
May 22, 2013 at 11:07 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
Could your problem be that "users.id" is actually an ARRAY, not a single value? Perhaps try it again with "users.id[1]" (I only have CF8 here at work). ... read »
May 22, 2013 at 7:52 AM
Nested Views, Routing, And Deep Linking With AngularJS
Hi, Just a quick thank you. As it happens, for my own purposes, the pending ui-router work being done in native angular is likely the one I'll adopt, but your exploration, code and documentation of ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools