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.

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>
    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.