Sorcerer's Tower

Why Railo?

In the near future I'll be getting myself a dedicated server, and decided to find out if anyone would be interested if I was to setup Railo hosting on it. So, I posted on the CF-Talk mailing list to see if anyone was interested, and crikey, what a reaction I got! The discussion is currently the longest in the past four dozen threads.

The first few replies basically boiled down to was "why would anyone want Railo hosting?!?".

Tempting as it is to reply with "Railo PWNS U l4m3rz!", I've decided that I'll instead explain why I choose Railo, over all the other CFML engines available (CFMX, BlueDragon and Smith being the significant alternatives).

However, to prevent me from rambling on for hours about how wonderful Railo is -- and I really could talk about it all day -- I am simply going to pick just five things that should help to show what attracts me to Railo. (but if you have any specific questions, feel free to ask them)

So, without any further ado, here are my five:


1. cfdump

One of CFMLs greatest tags, you might wonder how cfdump can be improved.

Well to show how Railo has improved it, imagine you are trying to debug a function, and need to dump out some data.

In CFMX, you could do it like this:

<cfdump var="#Arguments#" label="args"/> <cfdump var="#qrySomething#" label="qry"/> <cfdump var="#cfcatch#" label="catch"/>

But in Railo, all it takes is:

<cfdump eval="Arguments"/> <cfdump eval="qrySomething"/> <cfdump eval="cfcatch"/>

The eval attribute is a brilliant addition that not only saves you having to insert hashes every time, but also automatically labels each dumped output with what it is you are dumping.

It's a minor thing, but if (like me) you do a lot of dumps, it does make a difference.


2. cffile/info

In Railo, the cffile has an option for the action attribute called info.

As you would expect, it returns information about a file, such as filesize, last modified, and (for images) dimensions.

As an example of how useful this is, consider the following code which will check if a file exists, and if it has not been recently modified and is not smaller than a hundred pixels wide, you want to create a thumbnail from it.

In CFMX8, you might be able to do the following:

<cfdirectory action="list" dir="#ImgDir#" filter="#ImgName#" name="dir_info"/> <cfset CreateThumb = True/> <cfloop query="dir_info"> <cfif file_info.name EQ ImgName> <cfif file_info.dateLastModified GTE orig_img_date> <cfset CreateThumb = False/> <cfelse> <cfimage action="info" source="#ImgDir#/#ImgName#" name="img_info"/> <cfif img_info.width LTE 100> <cfset CreateThumb = False/> </cfif> </cfif> </cfif> </cfloop> <cfif CreateThumb> <!--- TODO: create thumbnail ---> </cfif>

But look at how I'd acheive the same result with Railo:

<cffile action="info" file="#ImgDir#/#ImgName#" name="file_info"/> <cfif (file_info.RecordCount EQ 0 OR file_info.dateLastModified LT orig_img_date OR file_info.width GT 100)> <!--- TODO: create thumbnail ---> </cfif>

3. cfloop/file

Ever had a huge file but not wanted the entire thing in memory? I have.

With MX, you have to read the entire thing, or delve into the underlying Java.

With Railo, you can just do this:

<cfloop file="myLogFile.log" index="line" startLine="500" endLine="560">

And bingo - you have only the parts you need, loaded one line at a time.


4. Queries, Arrays and Structs

I don't think I need to say anything here - I'll let the examples speak for themselves.

MX:

<cfscript> Bob = ArrayNew(1); Bob[1] = "apple"; Bob[2] = ListToArray("ball,bounce,bunny"); Bob[3] = ListToArray("carrot,chocolate"); Bob[4] = ListToArray("dandelion,dog"); </cfscript>

Railo:

<cfset Bob = Array ( 'apple' , Array( 'ball' , 'bounce' , 'bunny' ) , Array( 'carrot' , 'chocolate' ) , Array( 'dandelion' , 'dog' ) )/>

MX:

<cfscript> Caol = StructNew(); Caol.C = 'Clouds'; Caol.A = 'Amble'; Caol.O = 'Over'; Caol.L = 'Loch'; </cfscript>

Railo:

<cfset Caol = Struct ( C: 'Clouds' , A: 'Amble' , O: 'Over' , L: 'Loch' )/>

MX:

<cfscript> Alice = QueryNew("A,B,C");

QueryAddRow(Alice); cr = Alice.RecordCount; Alice.A[cr] = 3; Alice.B[cr] = 5; Alice.C[cr] = 9;

QueryAddRow(Alice); cr = Alice.RecordCount; Alice.A[cr] = 8; Alice.B[cr] = 4; Alice.C[cr] = 8;

QueryAddRow(Alice); cr = Alice.RecordCount; Alice.A[cr] = 7; Alice.B[cr] = 2; Alice.C[cr] = 2; </cfscript>

Railo:

<cfset Alice = Query ( A: Array( 3, 8, 7 ) , B: Array( 5, 4, 2 ) , C: Array( 9, 8, 2 ) )/>

5. Resources

And finally, Resources. A concept unique among CFML engines to Railo, a resource is basically a virtual filesystem.

With Railo 1.1's resources, you can create this vfs in assorted ways, and then simply add a mapping and use it with cffile, like this:

<cffile action="write" file="/output/#MyFile#" output="#Content#"/>

The /output bit maps to the resource - in Administrator you could set it to any of the following:

ftp://username:password@ftp.domain.com/myfolder ram:///tempdata c:/backup/archive.zip

Behind the scenes Railo will either FTP your file, store it in RAM, or add it to the zip - your code doesn't need to know where the resource points to - it just works.


Okay, now that's just five of the reasons Railo is my personal choice of CFML engine, but hopefully it's clearer now what I see in it.

If you still need convincing, feel free to leave comments, or take a look at the official Railo Blog which covers some of the features which I haven't gone into.


Oh, and if anyone reading this is interested in Railo hosting, please do let me know!


UPDATE: I have written another article which expands on this one, offering twenty reasons why you should choose Railo.

Posted:
07 February 2007, 21:36
Tags:
CFML
Railo
Web Development

There have been 9 comments.

Chris @ 2007-Feb-09 08:49
One more reason FOR Railo: It is much faster than CF... especially when it comes to handling CFCs and structs.
nick tong @ 2007-Feb-09 21:02
Hi Peter, i've not looked a Railo much but if it's so great why aren't people using it? What are the main draw back that you see?
Peter @ 2007-Feb-09 21:48
Hi Nick.

Lack of exposure is probably the main one - most things need a buzz to get going, and Railo hasn't really had one yet.

Featurewise, I can only think of one drawback - converting strings to dates requires the ParseDateTime function (a sacrifice made to improve speed), and still isn't brilliant.
Probably some other similar things... as mentioned in the CFTalk thread, it doesn't support dots in variable names (also for perfomance reasons).

But these are definitely minor things when compared to the numerous improvements - and I hope its just a matter of time before more people see this and start to use it. :)
Gert Franz @ 2007-Feb-12 09:51
Peter,

you see. Performance is exactly the reason why we do not support implicit date parsing. You would have to do the checking in every comparison. I mean every. That's what CFMX does.
We are thinking about supporting the "." notation in variables though. But other things require our attention at the moment. And it is really easy to avoid "." notation in your code.

Nevertheless. Thanks for all your support. We appreciate it. In fact the third hoster in Switzerland has just decided to go Railo. :-)

Gert
Peter @ 2007-Feb-12 13:21
Yup, I understand the reasoning, and also prefer it now - it encourages dates not to be stored as strings, which avoids a lot of problems.

I also think you should remain with not supporting "."s - it just causes confusion.
xig @ 2007-Mar-30 17:50
About the "."

We're planning to try out Railo with a significant conversion of an existing and fairly complex CF site to Railo. Can you clarify:

a) You can't use . in a variable name, only in a path or struct. So myStruct.foo is ok - but it means there's a variable called foo IN a struct.

or

b) You can't use dot notation at all to access variables in structs (or scopes? what about e.g. request.foo ?)

I'm hoping the answer is "a"...

thanks,
Peter @ 2007-Mar-30 20:42
Yes, a is correct, you can use dot notation.

Goodluck with your conversion! :)
Peter @ 2007-Mar-30 20:51
Oh and just to clarify a bit further, if you /need/ to deal with variables with dots in their name, you can use bracket notation.
eg:
<cfset Request['myVariable.foo'] = "bob"/>
creates a var in Request - there is no Request.myVariable struct when doing it that way.

But trying to use Request.myVariables.foo after that will cause an error, and setting Request.myVariables.foo will create a struct called myVariables.

Hopefully that does help and hasn't confused the matter?
xig @ 2007-Apr-01 06:19
That's great, thanks.
Registered Members
If unregistered, leave blank.
If unregistered, leave blank.
Unregistered Guests
Identifies your comment
Not displayed publically. Allows new comment notifications, or for the blog owner to contact you.
Link your name back to your personal website.
Comment