This blog is now obsolete. Go to scott.arbeitman.id.au for all new content.

Showing posts with label coldfusion. Show all posts
Showing posts with label coldfusion. Show all posts
1

Moving to Ruby Full Time

| Thursday, May 14, 2009

I recently started new job, which has involved near full time Ruby on Rails development. I have previously done some minor projects in Ruby and Rails, but for the most part, I have been using some combination of ColdFusion, Java and PHP for most of my professional career. I thought I would note some of my observations about using Ruby as compared with some of the other languages.

Readability: Ruby is well known as the "glue that doesn't set" meaning that Ruby code remains easy to read, even after a leaving it for a significant amount of time. This is hard to argue with. Anyone who has ever explored a Rails model or read an RSpec test can easily see some of the virtues of Ruby. Compared to most language, Ruby wins hands-down. But, the problem arises when it comes to

What-the-hell-is-going-on-ity: The readability of Ruby comes from its many metaprogramming features. RSpec does a great job of adding the right methods to Ruby classes, as does Rails. But this means that a lot of code or methods are added for you. Control flow and the definitions of methods become difficult to pinpoint. The more simultaneous frameworks you use, the greater chance of confusion. All this while your code remains quite easy to read. But what about trying to debug or add new features. This is where the problems start to creep in. By using the much more verbose Java, we can still have our dependancies documented and explicitly referenced in our code. Yes, this creates noise which makes our code harder to read, but it also leaves breadcrumbs as to what is happening.

Community: This is sometimes overlooked when considering which language to learn. It doesn't just matter the size of a community, but the quality of it. ColdFusion has a relatively small community, but is active and friendly. I can easily name the hot-shots of ColdFusion and I can subscribe to their blogs with too much information overload. In contrast, the Java community is probably too big. Frankly, I wouldn't know where to start when looking for blogs to subscribe to.

Ruby is a funny creature. The Ruby community seems small. On the other hand, the Ruby on Rails community is large. It's rare to find a Ruby programmer who doesn't use Rails. And Rails certainly has its "key people" and finding Rails tutorials and podcasts is pretty easy. You're not likely to find such a wealth of knowledge for most other frameworks like Model-Glue or Spring. But if you're interested in Ruby qua a programming language, you can get a great start here, but good luck after that. This can keep you from writing really excellent Rails code for quite some time, somewhat delaying superior readability of your Rails code.

Perception: Justified or not, ColdFusion gets a bad rap as dying and/or expensive platform. I've been hesitant to dive head first into the world of ColdFusion since I'm unsure of its future. Ruby, by all accounts, is, has been and will continue to be on its way up in the world. Rails too. With its adoption on the JVM and .NET, its attraction will only grow. Java, in comparison, seems stale and while its probably not going anywhere, it's best days are probably behind it.

Employability: Most Ruby jobs are Rails jobs. Knowledge of other frameworks are usually not required. Although Rails incorporates features from a number of frameworks in the Java world (Hibernate plus Spring MVC, for example), it is still a single framework. You either know Rails or you don't, and it is rare you will receive a Ruby language exam when applying for a Rails job. In contrast, Java jobs often require in depth knowledge of Java (garbage collection, intricacies on serializability, the Liskov Substitution Principle, etc) and knowledge of several Java frameworks (Java EE, Spring, Hibernate, Axis or whatever). This is a lot know, and it forces Java programmers to pick their niches early in their career and makes it hard to break out of it. For example, can you really go from being a Spring middleware guy to write UIs using the Google Web Toolkit? Not easy, to be sure.

ColdFusion has the opposite problem: if you know the language, that is usually sufficient. Sometimes, experience with an [any?] MVC framework is desired. Of course, if you know Rails, for example, then you do know an MVC framework and really shouldn't hesitate to apply.

Sum it All Up

So what does this all mean for you? Well, if you're interested in the web space and you don't mind somewhat limiting yourself there for the time being, Rails is a good place to start. But because you probably don't know Ruby of Rails, there is going to be a steep learning curve.

If you have confidence in ColdFusion and its future, I have certainly enjoyed my team in that space, but you should really force yourself to understand and integrate with the Java world that powers it. That should cushion you, just in case pessimists like me are right. Learning an MVC framework like Model-Glue, or learning to integrate with Flex front-ends would be time well spent too.

If you've just finished university, chances are you already speak Java. This is great, but is really just the beginning of the skills you'll need to work in the Java world. Learning a couple of Java frameworks (Spring and Hibernate go well together) should help you find that first good job.

If you are otherwise an experienced Java guru, look at Rails with JRuby. You might realize you have been writing way too much code that nobody else can read.


0

The End of ColdFusion

| Thursday, September 18, 2008

The marketing gurus at Adobe have just released an Evangelism Kit for ColdFusion [via Damon Cooper's Blog].

For as long as I've been using ColdFusion (over 3 years), I always heard detractors saying it was a dead or dying product. We never got much help from Adobe (or Macromedia) in justifying ColdFusion; we were forced to speculate on the future of the product, and the number of customers using it. I suspect that Adobe never had the need to justify CF; sales were fine, and so too, most likely, were revenues from the product.

So now I am going to become one of those detractors. Let's just say that this kit hasn't inspired me. On the contrary... I can't but feel that this Evangelism Kit spells the decline of ColdFusion. Here are few things to consider:

  • Why now? 10+ years without such an offering. Why create this document now? I suspect that some of the major clients listed are actually migrating away from CF, so better to indicate that these companies are using CF while it is still technically true.
  • Where are the exciting new features? I mean, look at the roadmap. Sully features "enhancements". I'm surprised "bug fixes" didn't make it onto that list.
  • Open source competition: Blue Dragon, Railo and more
  • Leveraging other products and scripting languages as middleware in the RIA stack: Groovy (the boys at Broadchoice, filled with names synonymous with ColdFusion, are using Groovy more and more these days: 9 posts tagged with "Groovy", zero posts tagged with "ColdFusion"), PHP, and Ruby.

I like ColdFusion, so I hope Adobe can keep it alive and keep its developers highly productive, but just when I think Adobe will push to make CF mainstream, I feel they took at least one step backwards, and may not have any more momentum to move forward.


0

Building a Better CFLOOP

| Saturday, June 23, 2007
ColdFusion 8 introduces slightly improved looping for arrays, as well a new way to loop over the contents of the file. Unfortunately, I don't believe these changes go far enough and, as I'll demonstrate, even better results can be accomplished even with older versions of ColdFusion.

My improved looping tag uses a little known ColdFusion feature, the <cfexit method="loop" /> tag. When used inside a custom tag, this returns control to the top the tag's "end" execution mode. This is ColdFusion's way of allowing custom iterators.

Here's what the syntax of my array looping tag:


<cfimport taglib="/custom-tags/loop/" prefix="loop" />

<loop:array array="#myArray#" index="i" element="e" cycle:shading="light,dark" cycle:odd="true,false" cleanup="true">

</loop:array>


Let me break it down:

  • array: this is the array you want to loop through, just like a regular CFLOOP

  • index: again, just like in CFLOOP, except this attribute is not required and has no defaults. it simply is not set.

  • element: the current item in the array. By default this a variable called element

  • cycle:variableName: the tag sets variableName to one of the values based on current index. This is inspired by a similar function in Rails. For example, in the above example, the variable odd will either have the value of true or false depending on the iteration number.

  • cleanup: This is perhaps the nicest feature. cleanup will remove references to all variables created during the iteration of the tag. This eliminates the need to var-scope lots of variables inside a CFC. By default, this is true.

Update
I've posted the code on github.
1

ColdFusion and YAML

| Tuesday, April 24, 2007
One interseting thing in Ruby on Rails that's sorely missing in ColdFusion is YAML. For those who don't know, YAML is similar to XML or JSON, and is a way to represent complex data or objects. YAML is extrememly lightweight and less verbose than XML.

After a little server configuration, it's easy to turn YAML text in a file into a ColdFusion structure.

I'm using JYaml as my YAML parsing library, but other options are available. Unfortunately, JYaml requires Java 5, which is not the standard ColdFusion operating environment. To remedy this, download a Java 5 JRE and follow Ben Forta's concise directions. Don't forget to put the JYaml jar file in your classpath and restart your ColdFusion server.

Assuming your .cfm file and .yaml file are in the same directory, creating a ColdFusion structure out of it is a easy as:


<cfscript>
Yaml = CreateObject("java", "org.ho.yaml.Yaml");

configFile = CreateObject("java", "java.io.File").init(ExpandPath('.')&"/settings.yaml");

settings = Yaml.load(configFile);
</cfscript>


Dumping the "settings" variable reveals exactly the structure you were expecting.

One caveat: you may experience unexpected behavior when trying to access your struct's properties using dot notation. Instead, use the "associative array" with square brackets option.

So do this:

value = settings['credentials']['username']

not this:

value = settings.credentials.username
2

Site Layouts and Application.cfc

| Sunday, April 22, 2007
A common problem for any site developer is maintaining a consistent layout across pages. Many frameworks have been designed to simplify this. Model-Glue, for example, can handle this by having the site template as the last view included in the response cycle. This a heavy approach if all you want to do is view decoration.

Let's take a look at solving this using the onRequest method in Application.cfc to capture our outputted content, and then placing it within a template. Here's a skelteton onRequest method:


<cffunction name="onRequest">
<cfargument name="thePage" type="string" required="true" />
<!--- Magic will happen here --->
</cffunction>


For those of you familiar with onRequest, you'll know that if we don't manually included the requested page, ColdFusion won't send any content to the browser. This might strike some people as odd, but it opens a world of possibilities. For example, see my previous post on using Application.cfc as the application controller in an MVC framework.

In this case, instead of invoking a method within the Application.cfc, we'll store what ColdFusion would have outputted into a variable using the cfsavecontent tag. We'll then include another .cfm page, which will have access to all the variables in the onRequest function, including the just-saved content of the included page. Thus, the onRequest magic looks like this:


<cfsavecontent variable="contentForLayout">

<cfinclude template="#ARGUMENTS.thePage" />

</cfsavecontent>

<cfinclude template="Layout.cfm" />


Now, the code within Layout.cfm has access to the contentForLayout variable which contains the dynamic region of your page. A simple layout could simply output the content within the HTMl body:


<html>

<body>

<cfoutput>#contentForLayout#</cfoutput>

</body>

</html>

Naturally, you've have a much more complex layout, where you'd include Javascript, stylesheets, a header, footer, etc.

Another very important consequence of this is that your Layout.cfm has access to all the variables available within your Application.cfc so there is no reason which your layout cannot content dynamic content.
1

Using Application.cfc as your application controller

| Thursday, April 19, 2007
A few months ago, I was experimenting with Model-Glue for an application. One thing that struck me as odd was that certain events which are normally handled by the Application.cfc (onRequestStart, onRequestEnd) were handled by Model-Glue controllers.

Rather than moving custom application event handling logic in a seperate controller, why not handle them with the Application.cfc? After all, the Application.cfc framework is a well-documented, frequently used ColdFusion features which already handles many application-level events.

To that end, I've written yet another ColdFusion MVC framework I call "Boca", which is Rails-esque insofar as mapping event names to controller methods (handlers) to view pages without configuration. But what makes Boca unique (and uniquely ColdFusion) is that Application.cfc serves as the controller for all application events. A sample Application.cfc would like this:


<cfcomponent displayname="My Great Application" extends="BaseApplicationController">

<cffunction name="onApplicationStart" ...

<cffunction name="onSessionStart" ...

<!--- Custom Event Handlers --->

<cffunction name="addToCart" access="public" returntype="void">

<cfargument name="productId" type="numeric" required="true">
<!--- Do application logic here --->

</cffunction>

<cffunction name="signIn" access="public" returntype="void">

<cfargument name="username" type="string" required="true">
<cfargument name="password" type="string" required="true">
<!--- Do application logic here --->

</cffunction>


</cfcomponent>


While I cannot make the source code public, I can offer insight on how to accomplish this in your application. The secret is using the onRequest function in Application.cfc to intercept calls, call the appropriate function within the Application.cfc, and include the corrent view page(s). This can all be done in less than 100 lines of code. To reuse this filter across Application.cfc files within your site, simply extend the base component which implements the onRequest method, and don't override that method.

If, like in other MVC frameworks, the event contains the union of FORM and URL scopes, I suggest invoking the event handlers using the event as the argument collection of the handler method like so:


<cfset event = StructNew() />
<cfset StructAppend(event, URL) />
<cfset StructAppend(event, FORM) />
<cfinvoke method="#action#" argumentcollection="#event#" />


You the get better event documentation by enumerating the arguments and types for your event handler (although this is optional, since ColdFusion supports dynamic arguments, and will also preserve the name-value pairs passed in). See the sample component above for an example.

A consequence of this approach is that variables set (and not var-scoped) within the event handlers are available in the view pages included within the onRequest method (this is a well-documented Application.cfc behaviour), saving Model-Glue like usage of event and view-state components across controllers and views.