The amazing adventures of Doug Hughes

Archive for July, 2006

My One Wish for ColdFusion

I’ve read the recent flurry of blog entries about wishlists for ColdFusion 8. (As have many people, given the popularity of the subject.)

Personally, I only have one real wish for ColdFusion 8:

I wish that Adobe would allow me to configure an application without ever having to log into the administration interface.

What does this mean? Well, for example, it annoys me that I need to have access to the administration interface to create any data sources and scheduled processes I might need for an application. This includes caching configuration, mail server configuration, event gateway configuration (that’s the main reason I don’t use event gateways) and so on.

I believe that an application’s configuration should be separate from the server configuration. In particular, it drives me nuts when I have to use absolute paths for configuration settings! Relative paths could save so many headaches!

My reasons for this belief can be summed up as:

An application’s configuration is specific to an application, not to a server.

For example, two different applications rarely share the same database. Obviously these two applications need different DSNs. Why should this information be set at the server level? In my opinion it shouldn’t. The same thing goes for scheduled processes, caching, etc.

To deploy a new I should not need to access an unrelated administrative interface for the server.

This is particularly relevant to shared hosting providers, or any company which restricts access to the administrative tools. This not only creates a barrier that developers must overcome, but it opens the door to errors when deploying applications.

For example, if all of the data sources, scheduled processes, etc, were configured in an XML file, I could easily write an Ant script to deploy the application and make any configuration changes I need for production. I could easily, turn off debugging, turning on trusted caching, changing the mail server to a real server, and so on.

In a nutshell what is currently a manual process could be automated.

I shouldn’t have to remember the configuration settings for each site. Half the time I forget to do something like configure a scheduled process

Because I have to manually remember to make configuration changes as I deploy an application I’m likely to forget a step. If this is something like a scheduled process that runs weekly, it could be quite a while before I realize my application is broken.

I shouldn’t have to share the server’s configuration between applications

This is the last real problem I have with server-based configuration as opposed to application based configuration. What if on one server instance, I want to enabled trusted caching for one application but not for another? Simply put, I can’t. I believe configuration choices like these should be made at an application level.

I propose that…

First off, the administration interface (and its API) remain unchanged. I do think that this should continue to allow developers and administrators to add data sources, and make configuration changes at the server level.

Additionally, I would like to see an XML file or another configuration format which can easily be manipulated programmatically be used to override the server settings for a specific application.

For example, maybe Adobe would create a .cfn file which could contain xml markup. When the application starts up it would look for a .cfn file in the root of the webserver and parse it to find out how that application’s configuration overrides the server’s configuration. For example, it might create a data source named “Foo” pointing to the MSSQL database “Bar”.

It might also define a scheduled process which executes the file at “/foo/bar.cfm” every four hours. Note that this is a relative URL and is therefore independent of the URL the site may be accessed on. This would allow for the exact same configuration settings for this process between two development, staging and production servers. Less moving parts means less room for screw-ups.

All in all, I think that configuration is a part of an application, not a server. A separate configuration file becomes part of the application’s source code would be very valuable. It would make deploying applications easier and it would help reduce accidental errors resulting from configuration mistakes. Lastly, it would allow for automated deployments of applications.

Time To Buck Tradition?

One of the first things I learned when I was first starting to work with Object Oriented Programming in ColdFusion was the concept of a ScopeFacade. A ScopeFacade is an object that encapsulates access to a given variable scope.

For example, you might have a CFC which, for all intents and purposes, wraps the Application scope. This CFC would have methods such as getValue() and setValue() which would get and set the specified values in the application scope.

This is nice because it condenses all your access to these scopes in to one specific location. It also allows you to swap this CFC out for a different implementation in the case that you’re working in an environment where you do not have access to the particular scope.

For many years now I’ve been using a particular CFC (included with ReactorBlog) as a scope faade. When you instantiate it you tell it what scope it’s wrapping. After that you can get and set values to your heart’s content.

The particular ScopeFacade I use makes a reference to the specific scope in its own variables scope. I do this to avoid having to evaluate each variable each time I use the CFC. For example, it boils down to the difference between:

<cfreturn evaluate("#variables.scopeName#.#arguments.name#") />

And

<cfreturn variables.scope[arguments.name] />

In the end, neither are pretty. I chose to go with the reference.

The thing is, about once a month, I make the same boneheaded mistake. I put a SessionFacade into the application scope! For example, I might do this by setting a variable-scoped variable in a Model-Glue Controller. I don’t tend to notice the problem until I move the site to production and my users start screaming about seeing other people’s data. (“It says I’m logged in as the CEO!” D’oh!)

That’s when I realize that to have an effective SessionFacade I need to instantiate it each time I need to use it. That way the reference is always to that particular user’s session. (Well, either that or run evaluate each time I want to interact with values.)

Doug’s Note: The other day Jared was trying to sell me on a ScopeFacade he wrote that uses undocumented methods to get and set values of a variable for a given scope. It may work, but, to me it smells funky. I don’t want to use undocumented features in a production app. The fact that I might need to do it indicates that scope facades might not be the right solution to the problem.

The question then is, if there’s no good implementation then why are we implementing at all?

My opinion on this is because of the lemming mentality. If one of the notables in the community says something then it must be the best way to do things! <cough>Duck Typing</cough>

Really, the primary argument is that a given scope might not always exist. However, if you’re using one of these Facades then you know the scope must exist! The argument seems self defeating.

What I’d rather see is people avoiding direct use of the scopes in their model and services layers. However, I think the use of session variables in controllers is perfectly acceptable!

For example, in Model-Glue, the framework already requires the Application scope and requires the Session scope for stateful redirects. Furthermore, if Session or Application variables are disabled you’ll probably know about that ahead of time and you’d need to so that you could change the implementation!

If you need a value to be provided to a CFC then pass it to the CFC. Or, if you need a collection of unknown variables within a CFC then pass the entire scope into the CFC as a struct. This will let you get whatever values you need without breaking encapsulation.

And, as one last point, many highly visible ColdFusion developers have recently been excited by the concept that maybe you really should use all the features provided by the Language. Mixins? Sure, if you can, why not? Duck Typing? If you can, and need to, then gopher it!

It really boils down to pragmatic programming. If you need to, and you can, then do it!

It’s generally agreed that Controller components serve the purpose of ferrying data around. From that perspective, and the fact that ColdFusion provides easy access to different variable scopes, it’s just fine for your controllers to access this data directly and pass it into your model and services. However, don’t let your model and services touch any scope other than Variables, This or Super directly. That would break encapsulation.

Looping over dates in ColdFusion

This was one of those things that I did today expecting it not to work. The problem was that I had a set of dates I needed to iterate over (from a start date to today). I thought to myself, Self, wouldnt it be nice if I could simply loop from the start date to today somehow?

And so, I decided to give it a shot and see what happened. This is the code I tried:

<cfloop from="#Example.getStartDate()#" index="date" to="#now()#">
    <cfoutput>
        #LsDateFormat(date)#
    </cfoutput>
</cfloop>

Much to my amazement it worked. The loop started at the start date (in this case June 15th) and looped up today, one day at a time!

Tag Cloud