Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
I am the chief technical officer at InVision App, Inc - a prototyping and collaboration platform for designers, built by designers. I also rock out in JavaScript and ColdFusion 24x7.
Meanwhile on Twitter
Loading latest tweet...
Ben Nadel at BFusion / BFLEX 2010 (Bloomington, Indiana) with:

Learning ColdFusion 9: Bug Using Implicit Structs Within Nested Function Calls

By Ben Nadel on
Tags: ColdFusion

Last night, when I was playing around with ColdFusion 9's new Object-Relational Mapping (ORM) functionality, I think I found a compile-time bug. I say compile-time because the following code throws an error even if I put a CFAbort at the top:

  • <!--- Load the girl object based on the name. --->
  • <cfset joanna = entityLoad(
  • "Girl",
  • { name = "Joanna" },
  • true
  • ) />
  •  
  • <!---
  • Override Joanna's properties with a new collection.
  • Because we don't know the IDs of the given properties,
  • we need to search for them by name.
  •  
  • NOTE: Use the "TRUE" uniqueness parameter to make sure that
  • these entityLoad() methods return a CFC, not an array.
  • --->
  • <cfset joanna.setProperties(
  • [
  • entityLoad(
  • "Property",
  • { name = "Athletic" },
  • true
  • ),
  • entityLoad(
  • "Property",
  • { name = "Brunette" },
  • true
  • )
  • ]
  • ) />

As you can see, all I'm doing here is loading a Girl.cfc instance and then overriding its collection of Property.cfcs. This throws the following ColdFusion error:

Unable to complete CFML to Java translation. Error information unknown node type coldfusion.compiler.ASTStructInitializer@189eab7

I narrowed down the problem to the fact that I was calling EntityLoad() as part of an implicit array that was being passed to a function call. When I moved the EntityLoad() calls outside of the SetProperties() call, everything worked fine.

At first, I thought maybe this was a bug with EntityLoad() or some other ORM feature; but, because this appears to be a compile-time issue, I wanted to see if I could duplicate the error with a much smaller bit of code:

  • <!--- Test method returns a struct. --->
  • <cffunction name="test">
  • <cfreturn arguments[ 1 ] />
  • </cffunction>
  •  
  • <!---
  • Get an array containing our nested struct that is returned
  • from the method.
  • --->
  • <cfset data = test(
  • [
  • test(
  • { foo = "Bar" }
  • )
  • ]
  • ) />

This simple demo also throws the ColdFusion error:

Unable to complete CFML to Java translation. Error information unknown node type coldfusion.compiler.ASTStructInitializer@1b5027d

I tried a whole bunch of different combinations of nested structs and arrays - it didn't matter. As long as the outer expression was a method call and as long as there were at least two levels of implicit object creation (struct or array) in which the inner-most one was wrapped inside of another method call, the error was thrown.

ColdFusion 9 definitely made some good steps forward with allowing us to pass implicit structs and arrays to method calls; but, it looks like they still need to iron some of the complex nesting that this sort of syntax invites.




Reader Comments

Hi Ben

Is this another bug? I have broken it down to it's simplest form.

var local.result = {};

// add the page details to result
local.result['page'] = 1;
local.result['records'] = 2;
local.result['total'] = 3;

local.result['rows'] = [];

cfdrop( local.result );

This all works as expected but add an if statement (which can be anything) and the array just vanishes. What is going on here?

if ( 1 == 1) {

};

var local.result = {};

// add the page details to result
local.result['page'] = 1;
local.result['records'] = 2;
local.result['total'] = 3;

local.result['rows'] = [];

cfdrop( local.result );