Ugh ... coldfusion

Purdy on 2003-08-21T14:21:06

Due to circumstances that are out of my control, I am doing some ColdFusion development work on a freelance project. I always enjoy tackling technical projects and learning new things, but I'm not having as much fun learning ColdFusion as I have been on other stuff. Granted, I'm still in the "baby-talk" phase of ColdFusion, but I thought I'd share a comparison of Perl code and ColdFusion code:

Here's a scenario where ColdFusion is a pleasure to work with:

<cfquery name="get_all_products" dataSource="ODBC_DSN">
SELECT id,title FROM products
</cfquery>
...
<cfoutput query="get_all_products">
<option value="#id#">#title#</option>
</cfoutput>

The same thing in Perl ... well, you know. I'd have to use DBI, setup the db handle, create a statement handle and iterate through its fetchrow_*, all with proper error handling, of course. :)

Here's a scenario where Perl cleans house. Let's say I have a Web form with multiple records with multiple input fields and so I name the fields with the naming convention fieldname_ID# (i.e. title_1, caption_1 ... title_52, caption_52). So in the code that would process that form, I could gather them up pretty easily with Perl (this is pseudocode):

use CGI;
use DBI;
my $dbh = DBI->connect( .... );
my $q = new CGI;
my @ids;
my $sth = $dbh->prepare( 'UPDATE products SET title=?,caption=? WHERE id=?' );
foreach ( grep( /^\w+_\d+$/, $q->param ) ) {
    my ( $id ) = /^\w+_(\d+)$/;
    next if grep { $_ == $id }, @ids; # I forget ... comma in there or not?
    push @ids, $id;
    $sth->execute( $q->param( "title_$id" ), $q->param( "caption_$id" ), $id );
}

But here's what my ColdFusion code looks like so far (*cringe*) ... again, baby-talk and not even working yet:

<cfset ids = ''>

<cfloop index = 'key' list = '#Form.FieldNames#'>
# Notice the line below. ColdFusion has some regular expression support
# but its regex functions do not return matches - just the position within
# the string. It has some match support, but if you use it, it returns
# an array of position markers where the matches took place - not the
# matches themselves. So I have to resort to replacing the non-digit
# characters out of the field name so I can deal with it.
# Oh, btw, this really isn't a valid comment - CF comments look like this:
<!--- This is a CF Comment --->
    <cfset id_num = REReplaceNoCase( #key#, "[^0-9]", '', "ALL" )>
# Ok, notice ListFindNoCase() ... how wacky is it to have case-sensitivity
# determined by the method name (yes, there's a ListFind() that is
# case-sensitive. Oh, btw, all variable names in ColdFusion are case-
# insensitive. So I could say ids, IDS or IdS in the
# line below and it wouldn't matter.
    <cfif id_num GE 0 AND ListFindNoCase( ids, id_num ) IS 0 >
        IDS: <cfdump var="#id_num#">
        <cfset ids = ListAppend( ids, id_num )>
    </cfif>
</cfloop>

<cfloop index = 'i' list = "#ids#">
    <cfset sku_field = "Form.sku_" & #i#>
    <cfset title_field = "Form.title_" & #i#>
    <cfset caption_field = "Form.caption_" & #i#>
    <cfset image_field = "Form.image_" & #i#>
    <cfset pricing_field = "Form.pricing_" & #i#>
    <cfset special_pricing_field = "Form.special_pricing_" & #i#>
    <cfset sql = "UPDATE products SET sku='" & Evaluate(#sku_field#) & ",title='#title_field#',caption='#caption_field#',image='#image_field#',pricing='#pricing_field#',special_pricing='#special_pricing_field#' WHERE id=#i# LIMIT 1">
    <cfdump var="#sql#">
    <cfoutput><P>SQL: #sql#</P></cfoutput>
    <!---
    <cfquery datasource = 'ODBC_DSN' name = ''>
    </cfquery>
    --->

</cfloop>

Fun Fun!

Peace,

Jason


Look at CFSCRIPT

petdance on 2003-08-21T14:49:45

It's been almost three years since I've done any CF, but I believe the CFSCRIPT tag will make life easier in these cases, as in:
<CFSCRIPT>
sku_field = "Form.sku_" & i
title_field = "Form.title_" & i
caption_field = "Form.caption_" & i
image_field = "Form.image_" & i
pricing_field = "Form.pricing_" & i
special_pricing_field = "Form.special_pricing_" & i
sql = "UPDATE products SET sku='" & Evaluate(#sku_field#) & ",title='#title_field#',caption='#caption_field#',image='#image_field#',pricing= '#pricing_field#',special_pricing='#special_pricing_field#' WHERE id=#i# LIMIT 1"
</CFSCRIPT>
so that you don't have to have everything in a CFSET tag.

Re:Look at CFSCRIPT

Purdy on 2003-08-21T14:52:36

Cool! I'll give that a shot - thanks!

Jason

Feeling your pain

kellan on 2003-08-21T22:44:11

I'm in the same position. I started a position last week where the there is a huge existing code base in ColdFusion. The idea is to move to using an open source dev platform (which is still being debated) but in the meantime....

My favorite little quirk so far is the lack of block specific variable scoping. For example variables created in cffunctions still have the same global scope as those created outside of functions.

You can get around this using CFscript's Var() operator to locally scope variables. But then you can't use any CFML constract, for example cfquery.

So a function can be sane, or useful, but not both.

Re:Feeling your pain

vsergu on 2003-09-04T20:36:58

You're worried about a piddly thing like variable scoping? I was permanently scarred by having to use ColdFusion back when it didn't have user-defined functions, and it continued to lack them for far longer than any non-CF programmer would have imagined. I don't think it really got them until version 5, and I'd be surprised if they were completely usable even today. That's what happens when you have a language designed for nonprogrammers, I guess.