Archive for July, 2008

StringBuffer vs. List

Friday, July 25th, 2008

Just a quick tip that Shayne pointed out to me (after I had spent a few minutes staring at my code), use StringBuffer if you ever need to have a modifiable string.

Coldfusion uses the Java String class rather than StringBuffer. This means that everytime you modify a string, ColdFusion creates a copy of it in the background and doesn’t de-allocate the old one. Obviously this can quickly eat through your server’s memory. If you plan on only doing a few string modifications (or never modifying it), go ahead and use ColdFusion’s built in string class. Otherwise it will be better to use a StringBuffer.  If you ever want to use a StringBuffer object as a normal ColdFusion string, just use the StringBuffer’s toString() method.

Another benefit to StringBuffer is the number of functions available to you for things like substrings and treating the string as an array.  For a good example of replacing a ColdFusion string with a StringBuffer see this post.

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>