CFML differences between Railo and ColdFusion 9/10 (Part 1)

by kai on 09/02/2013



As promised in my last post, I’m starting a short series of observations I made when working with clients here in Australia and New Zealand on porting CFML applications between ColdFusion and Railo.

Please note that this post (and the follow-up posts) is not meant to be judgmental in any way, it’s just supposed to deliver a neutral view of what I found to be different when working with real-world client apps. Both products have some subtle different takes on things and I think it’s very valuable to have at least some of them documented.

1. General observation: Railo is sometimes more strict on CFML

Take the following code example:

switch(arguments.action)
{
  case("approve"):
  {
    doSomething(arguments.whatever);
  }
  case("delete"):
  {
    doSomethingelse(arguments.anotherargument);
  }
  default:
  {
    //no action
  }
}

What would be wrong with this? Besides the fact that are are no break statements at the end of each case block (which might be intended), the way how the case statements are expressed is quite weird, isn’t it? Normally I would write a case statement more like: case “approve”: and not wrap the additional parentheses around the string to test for.

ColdFusion accepts the example above just fine (I personally think it shouldn’t, but that’s a different discussion) – Railo however stumbles over it at compile time. It turns out that it tries to parse case(“something”) as a function call (makes perfect sense to me) and as it can’t find a local function case, it doesn’t compile the template. This can obviously easily be fixed by removing the parentheses.

2. Boolean and how they convert to Strings

If you convert Boolean variables into Strings, it seems to me that Railo will always convert the value true into the String “true” and the value false into the String “false”. ColdFusion does that only at compile time. At runtime, true converts to “Yes” and false converts to “No”. I think this runtime behavior is essentially due to some backwards compatibility behaviour going back very, very far in ColdFusion’s history.

This would usually not create a big issue unless you output converted Boolean values to the screen, but can be easily fixed with some conditional logic or a quickly written conversion function if needed.

Here’s an example:

#true#
Output in both Railo and CF: true

#1 EQ 1#
Output in Railo: true
Output in CF: Yes

3. Different approaches when storing simple types

This is slightly related to the item above. ColdFusion stores simple type literals internally as String – this can be easily verified by running some Java reflection code against your CF variables. There’s nothing inherently wrong with that, it’s just the way how the ColdFusion team back in 2001/2002 decided they’d implement variable management when the move was made from ColdFusion 5 to ColdFusion MX.

Railo follows a different approach. In the majority of scenarios I’ve seen, Railo seems to preserve the originally intended type. Something like myBool = true; or myDouble = 5678.91 would be stored in their native Java types. This can in some instances create a performance advantage as conversions between String and the original type might not have to happen (that often). Does it make a big difference? Yes and No (and I’d have to do more and proper measurement to confirm that): If you were to convert between a String and a Double, let’s say, 10 times, it won’t have much of an impact. If you however had to do that 20 million times in a loop, I’m very, very sure your users would actually feel the difference very clearly.

More important though: There are some other instances where the two different approaches bubble up quite unexpectedly; think of serializeJSON() for instance:

serializeJSON(456);
Output in Railo: 456
Output in CF: "456"

Wrap-up of part 1

Not unexpected, there are differences in how ColdFusion and Railo treat certain parts of CFML. As said above, I’m not judgmental, I have a vested business interest in both Adobe ColdFusion and Railo being successful with what they’re doing. This series is just about making people’s life a bit easier in case you have to port an application in either direction. So much for part 1, I’ll hopefully probably get round to write and publish part 2 tomorrow, there’s more to come.

{ 4 comments… read them below or add one }

John Skrotzki February 9, 2013 at 7:37 pm

Thank-you for taking the time to do this. I will be very valuable document to help people jump from Adobe to Railo ( or vice-verse ).

Reply

Jason February 12, 2013 at 9:18 am

We are just one such group that is considering jumping from ACF to Railo; we await each part of these with great expectation.

Reply

Rick Smith February 12, 2013 at 9:41 am

Oh this is good! I’ve installed Railo and am currently playing with it for the first time (since like 3.0) as we speak. In “converting” all my sites I’ve noticed all three differences, but it’s very subtle. Everything tends to work [in general], but I’m finding these types of glitches here and there as I continue testing. Keep it coming!

Reply

Adam Cameron February 12, 2013 at 11:45 am

Excellent blog article.

I think the Railo behaviour with the case/label/parentheses thing is simply a bug in Railo, not something done by design. A case in point, if you change your sample code so only the first case has the parentheses… the code runs fine. So it’s not something they’ve decided to do on purpose. It’s a bug.

Equally, if it was interpreting the case-with-parentheses syntax as a function call, the error would be different: “invalid construct in switch statement”, rather than the “Missing [;] or [line feed] after expression” which one does get. It looks like it’s just getting confused to me.

It’d be great to hear from the Railo guys as to what the intent was here.

All that said… anyone who writes their case statements like a function call deserves all they get, I reckon! 😉

I look forward to your follow-up articles.


Adam

Reply

Cancel reply

Leave a Comment

{ 1 trackback }

Previous post:

Next post: