ColdFusion 9 and pure CFScript CFCs

Filed under: ColdFusion

comments (21) Views: 13,415

If you came to ColdFusion from a Java, C++, JavaScript, Actionscript, or any other script based background you might not be aware that ColdFusion has a completely separate syntax. It looks very similar to those other languages but has always been sort of a bastard step-child of the tag based syntax. It wasn't as full featured, and wasn't talked about much. With the release of ColdFusion 9 in late 2009 Adobe made a concerted effort to bring CFScript syntax up to par with tag-based. One of the primary focus points was allowing developers to write ColdFusion Components in pure script. As part of my recent pastebinCFC project, I made the decision to write this new CFC in full CFscript. I wanted to take a short blog post to point out some of the things that I discovered while writing this project.

To start with, CFScript CFCs are much more terse than their tag based brethren. Less code means less typing, which converts to working faster and more efficiently. Let's compare an uber simple tag based CFC with one that's writte in script. Well use a simple bean object which is commonly used in MVC frameworks to store encapsulated data and pass it around.

Update: Dan Skaggs sent over a simpler version of the tag based CFC. I'm adding it here inline. Thanks Dan.

Now let's look at the same CFC written in script, with the same functionality.

Whoa, whachoo talking about Willis? It's less than half the lines of code, and I don't even have method definitions in there for the getters and setters! How's that supposed to work? Well, for starters, in CF9, you can use property to imply properties that comprise your object. In this case we have a string property called username, and another called password. Not only does that define, and create variables for us, but it also type checks them. And with CF9 the ColdFusion engineering team added support for something called implicit getters and setters. This takes every property defined in the object and "writes" virtual methods FOR you. You'd use them the same way.

Not only does it allow me to streamline my code, but you'll notice that when I create a new instance of my object, I don't even have to call the init method. ColdFusion will look for a method named init, and fire it if it exists.

Hope this helps you move forward in your usage of ColdFusion.

Amazon logo

If this article was interesting, or helpful, or even wrong, please consider leaving a comment, or buying something from my wishlist. It's appreciated!

Andy...to be fair to tag-based CFC's, you can do implicit getters and setters there too with a accessors="true" attribute to the cfcomponent tag. Doing that alone would remove 2/3 of the code in your example. Likewise, you can use cfproperty tags in your psuedo-constructor for the tag-based CFC and then use those implicit getter and setter methods in your init the same way you've done in the script-based CFC. I've said this in other places and realize I'm in a very small minority, but I personally detest script-based CFCs. I came to ColdFusion from the HTML world and not from C++ or any of the other programming languages that use this syntax. To me, the syntax for cfscript, while less verbose, is also less intuitive. You have these magic words hanging out in space that you have to remember the order for in order for them to work (eg public string function foo() or required array argumentName). To me, with my programming background, it's much clearer what's going on when you use attribute/value pairs in tags than when you use cfscript. My other problem is one of productivity. For example, I can write an indexed cfloop in tag syntax without even thinking about it but if I want to do it in cfscript, I invariably have to go look up the syntax and then try to figure out what I've borked when it doesn't work. Eventually the syntax might be as second-nature as tags are to me today, but for now, when I have to be productive and get stuff done, it's a productivity drain to deal with cfscript. Thankfully, CFML still supports both script and tags so, to each his own.

Dan Skaggs - February 01, 2011 06:22 am

+1 for cfscript! :)

inj - February 01, 2011 06:55 am

Full support for cfscript finally makes ColdFusion feel like a real language. I think you're missing an extra * on your Javadoc-style comment. /** @accessors true */ Without the double **, it's just a normal comment. Also, not to nitpick too much (sorry), but I would call them synthesized getters and setters and not implicit getters and setters, since you still need to call the functions in order for them to be executed. If they were truly implicit, if you tried setting the property directly, the execution would be automatically routed through the setter. For example, user.firstName = "Tony" would automatically call user.setFirstName("Tony") behind the scenes. Granted it seems like everybody calls them implicit, but there's definitely a difference.

Tony Nelson - February 01, 2011 07:55 am

I definitely like the newer syntax but find that the syntax highlighting in CFEclipse for it isn't that great. How is it with in CFBuilder?

jalpino - February 01, 2011 08:14 am

@Dan...

You make really good points about cfscript. If ColdFusion only had cfscript, I probably wouldn't have started using it 10 years ago. At that point the only programming experience I had was with HTML, and a little PHP. ColdFusion was easy to learn because it looked like what I already knew.

The reason I liked script based now though is because I do so much JavaScript. With the addition of the new operators in CF8 and CF9 it's even more like JS to me.

Dan, would you mind showing me how my example could be different? I always hate when ppl try to make one example look intentionally long and complex. I'd be happy to post it here in the comments if you email it to me.

@Tony, no nitpicking allowed! Seriously though, thanks for pointing out the difference, and for the error in my comment syntax.

@jalpino the highlighting in Builder is excellent, as you might expect.

andy matthews - February 01, 2011 08:49 am

@jalpino, CFBuilder has highlighting for cfscript. I haven't used CFEclipse in a while, so I don't know how it compares, although I've heard that in the latest CFEclipse, it's really improved in that sense. @Tony Yeah, it seems like in every other language, "implicit getters and setters" refers to what you're talking about, except for CF. In CF it's more like "automatic getters and setters." Railo does have implicit getters and setters like you're talking about but they call it "magic functions": http://www.markdrew.co.uk/blog/post.cfm/railo-orm-and-magic-functions @Dan I've been totally in your camp concerning cfscript for a long time, but I've lately started to code my cfc's in cfscript and I'm getting used to it and starting to like it. It has nothing to do with having some sort of inferiority complex about CFML (tags) not being a "real language", though.

Tony Garcia - February 01, 2011 08:52 am

Nice post Andy. Just want to point out that i prefer to use the 'non-commented' syntax of setting up scripted cfc's. In the case of (to ensure implicit setters/getters) /* @accessors true */ component { } You can have component accessors="true" { } +1 for full script support!

jbuda - February 01, 2011 09:06 am

Great post Andy, I was singing the praises of the tag based syntax just a couple of days ago on Twitter. @SirRawlins. I've recently started working on a project which will be running on a CF9 platform so we made the choice to run with script based cfc's and you are totally right, it really is much cleaner and easier to write. Going back to legacy code feels very unorganised and clunky. My one and only reservation with it, is the lack of support on older platforms. I feel that this means on the most part open source projects and blog posts will not be written using the script syntax, and so to the outside world it may still appear that CF is mainly a tag based syntax, which will deter developers looking to migrate from other platforms I would imagine. Thanks for the article. Robert

Robert - February 01, 2011 09:08 am

@jalpino - If you're not already, the CFEclipse Dev or Preview branches (cfeclipse.org/update-dev or cfeclipse.org/update-preview) offer much improved script-based CFC highlighting. The dev version, 1.4.5.x, has pretty solid script-based CFC highlighting.

Craig Kaminsky - February 01, 2011 11:21 am

@everyone - thanks for the replies. @craig - I've updated to 1.4.5 and it is a huge improvement, thanks for the recommendation. I had been running 1.4.4 and without surround the component in [cfscript] tags I had no highlighting. This is great!

jalpino - February 01, 2011 03:57 pm

Thanks for the post. I was a diehard script-hater until we upgraded to CF9 and I started using it. Now I try to write as much as possible in script, and am having more fun writing code than I have had in years! One thing that still bothers me though is doing the javaDoc style thing for the accessors=true. Having the content of comments affect how the code works just seems... wrong or something.

Mark Gregory - February 01, 2011 05:30 pm

@Tony Nelson: This is an interesting distinction and I wonder if CF does not actually use the accessors behind the scenes as you think an implicit accessor should. If you dump an accessor you get this as output: 'coldfusion.runtime.ImplicitGetter@5d4db0d4'. If you have accessors off, however, it would be ard to tell if CF is still using them when you set a property directly as you can't grab the method used behind the scenes... And you can always ask if ImplicitGetter is still synthesized.. But I suspect it is using a java based real accessor, so...

William Broadhead - January 18, 2012 05:54 pm

Hi All,
I am bit confused about providing path to a CFC by the above if it is present in some other location not in the same directory where we are creating the Object.

Can anyone please help me?

Makhan - September 13, 2012 08:37 pm

Makhan...

If I recall, CreateObject is expecting a path to the CFC relative to the calling object. Here's a few links for you:

http://www.sitepoint.com/forums/showthread.php?620658-calling-a-cfc-from-cfset-tag

andy matthews - September 15, 2012 08:07 pm

Yes, but how can we pass path to initialize a CFC using "new".
Like you have written:

new User(username='thumbelina', password='longhair');

Makhan - September 16, 2012 04:45 am

Hrm...

I really haven't used the "new" syntax much. Have you tried the following:

new path.to.User(username='thumbelina', password='longhair');

Don't know if that'll work but it's easy enough to try.

andy matthews - September 16, 2012 06:34 am

Yes, looks like that's the way to do it:

http://cfsimplicity.com/10/the-simplicity-of-coldfusion-9-part-2

andy matthews - September 16, 2012 06:36 am

Thanks for your Explanation.

Makhan - September 16, 2012 07:35 pm

I noticed a couple of errors in your code above. On thing I noticed out the gate is you are using the name="" in your component header, this is an invalid tag for cfcomponent. Displayname is valid but name is not listed in the docs as a valid attribute.

I also noticed even when using cfscript I have to add accessors="true" to my component header otherwise the implicit getters and setters don't seem to get generated. This seems to hold true even if I add metadata to the property tags.

Erin Duvall - February 05, 2013 03:29 pm

@Makhan - I believe you can use cfimport to import the namespace into your code. This would remove the need to call the cfc by the full path.

http://help.adobe.com/en_US/ColdFusion/9.0/Developing/WS61C07B60-3D65-4d71-8F2A-8411D8010E60.html

Erin Duvall - February 05, 2013 03:33 pm

@Erin...

Thanks for noting those issues!

andy matthews - February 06, 2013 06:05 am