Archive for the ‘Good To Know’ Category

ListContains means ‘contains’ in the literal sense

Thursday, October 2nd, 2008

Just a note, ListContains is basically the same thing as Find, except that it returns a list index.  It does not search for a specific element that matches the substring, but merely an element that contains it.

In order to find an element that matches the substring use ListFind.

CFInvoke vs. CreateObject

Friday, September 26th, 2008

Most programming languages have what are called static or class methods.  The other kind of method available is instance or object methods.  The difference between the two is that the former acts independently of any data members within the object.  Thus it can be called in passing without instantiating an entire object in order to use a small chunk of code.

Apparently the Coldfusion developers have never heard of these differences.  A tag called CFInvoke exists which would lead one to believe that this works like a static method call.  The first volume of the official Coldfusion text book even hints at this by using it in this way.  It even say, “… although rather than used, CFCs are said to be invoked.”

Well, not exactly.  If you use CFInvoke on an uninstantiated object (by using the component path), it will instantiate it for you.  Everytime. So instead of it being a memory saver, it wastes memory.

The proper use of CFInvoke is if you do not know what function will be called ahead of time and don’t want to have to have a switch statement for each potential function call.

Case Sensitivity In XML

Thursday, September 4th, 2008

Just a quick note to everyone trying to use XML in Coldfusion.  Don’t use a “true” parameter in XMLNew().  Things will go haywire.  Just use false and it manages to still retain all of the case sensitivity.

My hunch for why this makes things go haywire is that you cannot use the normal dot notation for accessing the sub-elements because CF capitalizes anything in the dot notation.

Another related note: don’t use the built-in XSLT processor.  It sucks and isn’t fully implemented.  Use cfexecute and get some sort of external XSLT engine.  The one I’m currently using is Saxon.  It’s slow, but it works.

Order in != order out

Thursday, July 24th, 2008

Because arrays in Coldfusion are based off of the vector collection in Java, they don’t always maintain their order in every instance.  If you use ArrayToList(), the order of the list returned will come out in whatever random order it happens to be stored in memory.  If you want a quick demonstration, use the following code:

<cfdump var="#ListToArray(StructKeyList(Variables))#" />

Just keep refreshing the page and you will see the order of the array keep changing.

To get around the weirdness with this, try using the java vector’s methods instead of CF’s array methods.  Just remember that the java methods use zero based arrays (versus CF using one based arrays).

Edit: That example isn’t entirely accurate. Scope variables are based off of abstract maps, but the concept is the same.

Structs Passed By Value (Copied) When Using “argumentCollection=”

Monday, July 7th, 2008

In ColdFusion I often find myself questioning whether or not I should pass data around by reference or value. Unfortunately in ColdFusion it’s transparent to the programmer what’s going on. Sure there are many blog posts citing the basic rules of thumb, however it’s always nice to test things out - just to be sure.

I recently ran into a situation in which I assumed ColdFusion was passing a struct by reference to a method - however, I things weren’t working correctly so I wrote up a quick test script to check what was going on. What came out of it was - ColdFusion apparently copies structs when they’re passed using “argumentCollection=” as a named argument in a method call.

Below is an example, tested on ColdFusion 8.0.1

<!--- Our simple struct to test reference vs value --->
<cfset qux = StructNew() />
<cfset qux.bar = "quux" />

<!--- Dump the fresh qux struct, our control --->
<cfdump var="#qux#" label="beforeFoo" />

<!--- Run foo() pass qux as an argumentCollection --->
<cfset foo(argumentCollection=qux) />

<!--- Dump showing that qux was passed by value --->
<cfdump var="#qux#" label="afterFoo" />

<!--- Dump qux as a control for foo2 --->
<cfdump var="#qux#" label="beforeFoo2" />

<!--- Run foo2() passing qux in as an argument --->
<cfset foo2(qux) />

<!--- Dump showing qux was passed by reference --->
<cfdump var="#qux#" label="afterFoo2" />

<!--- Functions --->
<cffunction name="foo">
	<cfargument name="bar" />
	<cfset arguments.bar = "baz" />
	<cfdump var="#arguments#" label="inFoo" />
</cffunction>

<cffunction name="foo2">
	<cfargument name="struct" />
	<cfset arguments.struct.bar = "baz" />
	<cfdump var="#arguments.struct#" label="inFoo2" />
</cffunction>

CFLoop - Cfscript, JSP, or CFML

Wednesday, July 2nd, 2008

We recently ran into a memory issue on Coldfusion while performing a fairly large loop operation. I suggest reading this blog post to learn more about this issue: http://www.nomachetejuggling.com/2006/12/07/coldfusions-compiler/

It talks in-depth about coldfusions compiler and the differences between cfscript and cfml compiling…some good stuff!

Possible Bug/Problem When Using DE Inside Of An IIf Function

Tuesday, July 1st, 2008

I’ll start by saying that this post and the example below were developed after reading Be Careful Using “#” In ColdFusion DE() Expressions by Ben Nadel. In a response to that blog post, Ubqtous responded with a comment that revealed an undocumented (?) feature and alternative to using the IIF/DE combination.

If you haven’t already read Ben’s blog post on this topic - I recommend reading through it to understand the code example below.

I added inline comments - though terse, they pretty much sum things up. I hope someone finds this useful, or it saves someone possibly hours of frustration.

<!--- Typical IIf/DE --->
<cfoutput>
    #IIf(
        true EQ false,
        DE("Hello, world!"),
        DE("Goodbye, world!")
    )#
</cfoutput>

<!--- Alternative to IIf/DE --->
<cfoutput>
    #IIf(
        true EQ false,
        "'Hello, world!'",
        "'Goodbye, world!'"
    )#
</cfoutput>

<!--- Why not to use DE? --->
<cfset strA = "(530) 555-1212" />
<!--- Remember this is escaped, really: #985 --->
<cfset strB = "##985" />

<!--- Typical IIf/DE --->
<!---
    This will crash!
    DE doesn't take into account escaped #s.
    Instead, it treats #s as a start of an expression.
--->
<cfoutput>
    #IIf(
        Len(strB),
        DE(strA & "x" & strB),
        DE(strA)
    )#
</cfoutput>

<!--- Alternative to IIf/DE --->
<cfoutput>
    #IIf(
        Len(strB),
        "strA & 'x' & strB",
        "strA"
    )#
</cfoutput>