ColdFusion 8 Per App Settings - Mappings

According to the documentation for this feature, Per App mappings allows you to dynamically set "logical aliases for paths to directories on your server." This sounds great but the code example in the documentation is wrong and this leads to a lot of frustration.

The first problem is that the docs show how to set a mapping for an application but not how to use it. We could experiment a bit and eventually find out the exact syntax needed except for the second problem - the example code given to set the mapping is wrong.

The documentation says to use the following to set a mapping of "MyMap" pointing to the location "c:\inetpub\myStuff".

<cfset this.mappings["MyMap"]="c:\inetpub\myStuff">
If we place a file called test.cfm into the "c:\inetpub\myStuff" directory we should be able to include it using standard cfinclude syntax. The problem is, no matter how we try, we can not get this to work.
<cfinclude template="MyMap/test.cfm">
<cfinclude template="/MyMap/test.cfm">
<cfinclude template="#MyMap#/test.cfm">
<cfinclude template="/#MyMap#/test.cfm">
<cfinclude template="this.mappings.MyMap/test.cfm">
<cfinclude template="/this.mappings.MyMap/test.cfm">
<cfinclude template="#this.mappings.MyMap#/test.cfm">
<cfinclude template="/#this.mappings.MyMap#/test.cfm">
<cfinclude template="this.mappings['MyMap']/test.cfm">
<cfinclude template="/this.mappings['MyMap']/test.cfm">
<cfinclude template="#this.mappings['MyMap']#/test.cfm">
<cfinclude template="/#this.mappings['MyMap']#/test.cfm">
Every one of the attempts above results in an error. This leads to a ton of frustration and a search across the net for working examples. The problem with that is that there are no clear cut examples showing how to make this work.

The solution lay partially in a blog post by Sean Corfield (Scazu Powered By ColdFusion 8) where he shows how he created a number of dynamic mappings for his application. In his example code he added a forward slash before the name of the mapping, something not mentioned in the ColdFusion documentation. This is the key. This single character makes the difference between frustrating failure and a successful feature. Adding the slash we get an setting of:

<cfset this.mappings["/MyMap"]="c:\inetpub\myStuff">
and a usage of
<cfinclude template="/MyMap/test.cfm">
Frustration solved.

So to recap, ColdFusion 8 allows an application to have dynamic mappings. These are defined in the application.cfc using a syntax of this.mappings["/MyMap"] where MyMap is the mapping name. Once set, the dynamic mapping is used like any other mapping with a syntax of "/MyMap/...".

One fast note - We can use any name we want for a dynamic mapping even if the name is in use by a mapping set in the administrator. The only restriction is that if we try to set a dynamic mapping with "/", an error will be thrown. We always have to have some text after the forward slash.

Forking

To quote Wikipedia on forking:

In software engineering, a project fork happens when developers take a copy of source code from one software package and start independent development on it, creating a distinct piece of software. Free or open source software is inherently prone to forking.

So basically there is no conceptual problem with forking an application. But what about legal? To quote part of a common open source license:

2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

Note the term "derivative works". ANYONE can take an open source project and alter it to their heart's content. If they plan to distribute it, they need to document their changes, but other than that, there is literally no law against the forking or modification of any open source project. The only question is: Should you?

In most cases, the answer is no. If you fork a project then it'll be hard to update your code with changes made to the original. It may even cause breakage of the original code. The only time you should fork code is when you know what you're doing and have a good reason to do it. Note again what I just said. Only fork code if you really need to and know what you're doing. If you fulfill those two conditions, then fork away. It doesn't matter if it's a modification to a small UDF or to a whole framework. As long as you're willing to take the risks and the consequences, let nothing stand in your way.

In other words, fork in knowledge, fork in safety, but let no one stand in the way of you forking.

As a final note, anyone who has added a custom layout or pod to BlogCFC has, in essence, created a personal (and minor) fork of that software.

Mach-II: My Final Words

I've been a little gun shy about posting recently. I stopped responding to a post about the use of the This scope. I did not follow up on the arguments for/against my actions with Mach-II. I did not follow up on anything because I got some rather negative feedback from people I respect. Their main argument basically came down to me looking bad because I was advocating altering a framework for perceived optimization.

This is my response on the matter, and if it gets me into more trouble, then so be it. The client I was working for was moving from ColdFusion to ASP. They were running on ColdFusion MX 6.1 and were not going to upgrade. They had a Mach-II application that had 363 method calls per page (213 mach II and 150 non-Mach II), which should not be the case. They were experiencing a HUGE delay per page for more than one or two people at a time and needed it fixed NOW. Yes, I altered Mach-II, along with other code, and it had a positive effect.

Were the number of method calls normal for a Mach-II application? Probably not. If any application used that many method calls, the writer would be shot, so this had to be an abnormal case. Would my alterations show any real speed increase in a well-designed Mach-II application? Again, probably not. I expect that a well-designed Mach-II application would use far fewer method calls and the total savings from the changes I made should be negligable. There are still a few places in Mach-II where I see possible improvements, and these have been sent to the Mach-II team for official review and inclusion. Will they have significant savings? See my answer above.

In the case I mentioned above, the client was happy and the contract was fulfilled. Would I do it again? Definitely! Why?

Because I'm an employee. So are you. We work for someone. We can offer our suggestions to them, let them know what we've seen and heard and try to move them towards proper code and procedures, but at the end of the day we are just employees. The client is always right, and if we feel otherwise, we can either suck it up or get a new client.

I get called in on emergency contracts all the time. When something is going wrong and it needs to be fixed immediately, then I get the call. For the client mentioned above, it required a fast and dirty fix. For another client, it required a fast fix for their "memory build and crash" problem and then an analysis of how to fix it. Sometimes the analysis leads to suggestions that 'break' OOP, but the end result is always the same. Better code for better performance.

Do I disrespect frameworks? Not at all. I'm one of the founders of the Fusebox framework (a methodology at the time). Do I advocate altering frameworks directly? My last post stated quite clearly that I do not feel that a framework should be altered except by those that know what's going on. On the other hand, if you know what's actually happening in the framework, feel free to alter it. But if you do, realize that you are essentially "forking" the framework, and any upgrades made to the framework cannot be reflected in your code unless you make some hands-on alterations.

But that's the beautiful thing of open source. Anyone can fork it. Anyone can remove the parts they don't want or need in order to tailor the code to their use.

What I did to Mach II

There has been a lot of interest in the steps I took to optimize my client's website. The main interest was in what I did to Mach II in order to speed it up, especially as Mach II is rather optimized to start with. The answer is to cheat.

If you look at the Mach II code you'll see that it's rather complex. It's also 1000% legal. Every component is documented as is every cfcomponent and cffunction tag. Output="False" is used everywhere needed, access is always defined, every cffunction tag has a returntype and every cfargument tag has both a type and a required when needed. It is this attention to detail and legality that gives Mach II and every other CFC based framework it's unexpected overhead.

Let's start with the cffunction tag. The returntype attribute performs a data validation on the information being returned from the function. Any validation operation has a certain amount of overhead and when the validation is done against a component reference then the overhead becomes more noticable. In addition, I find the returntype to almost be an insult. If I wrote the function then I should have a relative clue as to what it is returning. If the returntype is only being used for documentation rather than for actual validation, then that information can be put in the hint.

But wait! I'm not saying to remove the returntype. It is actually rather important to the operation of a function. What it does beyond data validation is tell ColdFusion IF the function is returning anything. For this reason I always have a returntype defined but its value will either be any or void. Any basically tells ColdFusion that the function is returning something but that it should not worry about validating it. Void tells ColdFusion that the function will not return anything at all. If a cfreturn tag is used within the function then an error is thrown.

Original cffunction tag
<cffunction name="getDefaultInvoker" access="public" returntype="MachII.framework.ListenerInvoker" output="false" hint="Returns an instance of the default invoker (EventInvoker) for this Listener.">


Modified cffunction tag
<cffunction name="getDefaultInvoker" access="public" returntype="any" output="false" hint="(MachII.framework.ListenerInvoker) Returns an instance of the default invoker (EventInvoker) for this Listener.">

The removal of the returntype alone causes a noticable speed increase for components that are heavily used. If we take the same idea of removing data validation and apply it to cfargument tags then we'll see even more of an improvement. There are actually 2 different types of data validation going on in a cfargument tag. The first is the same data type validation as defined above and this is defined by the type attribute. The second is a check for existance and is defined by the required attribute. The total removal of both of these attributes increases the savings we get from the removal of the returntype. I do one additional thing, though. I add a hint attribute to the tag, which will tell me what data type was expected and if it was required. This is for documentation purposes only, but does help when debugging.

Original cfargument tags
<cfargument name="eventName" type="string" required="true" />
<cfargument name="eventHandler" type="MachII.framework.EventHandler" required="true" />
      

Modified cfargument tags
<cfargument name="eventName" hint="(required - string) what the data should be" />
<cfargument name="eventHandler" hint="required - component) MachII.framework.EventHandler being passed in" />

The removal of the type and/or required attributes from the cfargument tags is not without consequences. There are times where a function needs to be sure of the data being passed in. I judge these on a case by case basis, but when it comes to Mach II I didn't even bother. Mach II is so solid in its construction that every function is very exact in what gets passed to and from it.

As a final warning, remember that Mach II is a closed system that has been heavily tested and is only modified by a select few. No one is supposed to be touching the core code other than those select few. Because of this strict control, I felt very confident in my alterations and they worked flawlessly. In the end thats all that matters to a client...has the job been done.

I don't hate Mach II

I was doing a remote presentation last night on "Object Orienter Programming for ColdFusion Developers" and it eventually moved over to the topic of optimizing ColdFusion Components. While I was showing what I do for speed, I relayed a story about a client of mine who is using Mach II. I was brought in to speed up the clients site which was timing out on a regular basis.

After a review, I found some places that could be optimized and one major place was the Mach II code. I rebuilt most of it and the time savings was immense. Of course, in order to make it faster I had to cheat and break many of the accepted 'rules' of OOP and CFCs. Not something that I suggest anyone doing without a full understanding of the how and why of it (which I'll talk about another time).

After telling the story and showing what I did, someone assumed that I did not like Mach II and asked what Framework I used. I quickly corrected his conclusion and told him not only do I have nothing against Mach II, but it's a really well thought out and solid framework. I don't use it because I don't use any of the public frameworks. I'm obsessed with optimizing my code for speed and performance and really optimal code doesn't go hand in hand with frameworks. On the other hand, I stressed that using a framework is a MUST in almost all situations and that people should not go my route unless they really know what they're doing and have very strict control over who has access to their code.

Bottom line is that unless your a paranoid, obsessive, hermit programmer, use a framework!

FAQ-U 2 - OOP for CF and Frameworks

Yep, the second issue of the Fusion Authority Quarterly Update is not only in my hand, it's packed and ready to go to all subscribers. But of course, anyone who subscribes before the end of the year gets this issue as well as the previous one in PDF format as well. Trust me, PDF is nice to read once in a while, but nothing beats the solid feel of this journal.

As for content, we're talking an actual book worth of Object Oriented Programming for ColdFusion as well as Frameworks. 120 pages of it to be exact (20 pages over what we expected for this issue). But why listen to me when the table of contents speaks for itself:

Editorial

OOP in Your Toolbox
by Judith Dinowitz

Columns

What's Hot? What's Not?
by Raymond Camden, Simeon Bateman, Charlie Arehart, Kurt Wiersma, Michael Dinowitz
Tipical Charlie - How do I Call Thee (CFC)? Let Me Count the Ways!
by Charlie Arehart

Features

Object-Oriented Programming: Why Bother?
by Brian Kotek
The Object-Oriented Lexicon
by Hal Helms
Design Pattern Safari
by Peter J. Farrell
From User-Defined Functions to ColdFusion Components
by Michael Dinowitz
Base Classes: Better Than Your Knew!
by Peter Bell

Concepts

Introduction to Frameworks
by Jared Rypka-Hauer
Fusebox 5 Fundamentals
by Sean Corfield
Mach-II Fundamentals
by Matt Woodward
Model-Glue Fundamentals
by Joe Rinehart
Lessons I Learned from My First Model-Glue Application
by Jeffry Houser
ColdSpring Fundamentals
by Chris Scott
Reactor Fundamentals
by Doug Hughes

Tools

FusionDebug Explained: Interactive Step Debugging for CFML
by Charlie Arehart

And no, we're not going to kill you with advertising. We don't even have advertisers. What we have are supporters who are helping to make sure that we can get the journal to you. A big thanks to:

Adobe Systems, inc. - Makers of ColdFusion, Flex and much, much more

Intergral Information Systems - makers of Fusion-Reactor and Fusion-Debug

WebApper Services, LLC- Makers of SeeFusion

Quill Design - Maker of the SiteDirector shopping system

Straker Interactive - Makers of ZoomFlex

Liquid Image Studios - More creative design than you can shake a forest at

House of Fusion - Providers of quality ColdFusion and related technical content

You can order the journal right away and we'll not only get it to you ASAP but we'll give you access to a PDF of it to hold you over.

http://www.fusionauthority.com/quarterly

We accept orders through Google Checkout (USA Only - Preferred method), Paypal (World wide), or contact us for bulk orders and we'll work with you.

Execution Functions and Evaluation Zones

Waaaay back in 2000, I wrote an article on certain 'laws' of ColdFusion that I used: The Law (according to Michael Dinowitz)

One part of this article was a rundown of what I called Execution Functions. Basically, these were functions that either returned no value or a boolean to indicate success of failure. My 'hard' rule is that there is no need to assign the value returned from these functions to a variable and even that doing so is a waste of memory. I've rewritten that section many times in different places, but this is what is actually happening.

A CFSET tag is divided into 2 parts. One part is the evaluation zone, which is the right hand side of the tag after the equal sign (if an equal sign exists). The evaluation zone will treat anything that is not a number or a string as something to be evaluated. It will also look inside any string for anything surrounded by pound signs and try to evaluate it as well. This zone is a general evaluation zone, so you can even use something like:

This is a comparison which you may see in a CFIF, but will evaluate properly inside the CFSET. If the name variable has a value of "Michael", then the value of IsName will be Yes. Otherwise it will be No.

For an even older article that clearly explains evaluation zones, look here: Evaluation in ColdFusion

The other part of the CFSET tag is the variable assignment. This is a variable name followed by an equal sign and will accept whatever comes from the evaluation zone and assign it to variable. This area is TOTALLY OPTIONAL. There has never been a need to assign the value of the evaluation zone to a variable and doing so basically creates a variable that is usually useless.

So bottom line is that any CF function, UDF, or Component method call (which is basically a UDF) can be used in a CFSET without any variable assignment.

This is what I do and every time I see some code that is running a QuerySetCell() and assigning it to a temp variable, it's the first thing I erase.

You know, I really have to update and republish a lot of my old articles. Lots of good information just buried under the weight of time. :)

StructKeyExists vs. IsDefined when checking 2+ scopes

There has been a movement away from using the IsDefined() function to using the StructKeyExists() function. The reasoning is that when IsDefined() is used to find an unscoped variable, it follows a specific order of scope evaluation that goes through over half a dozen scopes (9 actually) in order until it finds the variable or fails. StructKeyExists() on the other hand requires a scope and limits the search to that scope.

Note: There is a thought in the community that StructKeyExists() is more efficient than searching for a scoped variable using IsDefined(). I can't comment on this as the difference is probably tiny.

Note: I say over half a dozen rather than 9 as some of the scopes 'exist' but are empty unless specifically used (cffile, url, form, client) or only exist in certain places like the arguments or the 'unnamed local scope' in a UDF.

Now all of this is fine and good, but what happens when a variable may exist in one of two scopes, such as Url or Form? In such a case, most people move back to an unscoped IsDefined() search. I suggest instead to simply use two StructKeyExists() functions and trust in ColdFusion's short circuited boolean evaluation to keep things efficient. All you have to do is make sure you check the scope where you expect the variable to occur most often first.

For example, this CFIF is expecting an email passed to it from an URL or Form. The URL is the most common way in which the email will be sent so I check the URL scope first.

If the email variable is passed on the url, then the second StructKeyExists() will never be processed and the end result is a single function use. In the worst case all you are doing is running 2 functions against 2 (probably small) variable scopes rather than running through half a dozen, at least one of which (CGI) is rather large.

Of course the use of 2 functions may be less cost effective and I await the word of someone like Sean who knows the inside of ColdFusion better than I.

Those who a simple explanation of short circuited boolean evaluation can read this Fusion Authority article from 2000 which details it rather simply: ColdFusion with Style

Interfaces - Why bother?

I've been watching people talk back and forth about including interfaces into the ColdFusion language or not and I've been wondering why bother. From what I know, interfaces (the Java keyword rather than the general term) are used to define what is basically a "rules class". This rules class contains the names of methods and any arguments that they may need. Any class that uses this rules class (implements it), must have a method within it of the same name (and arguments) or else an error will be thrown.

Basically an interface is a contract between a class and a rules class that says that the class has to have all of the rules' methods to be legal.

In ColdFusion terms, this means that there is a 'rules' component (an interface component) that only contains cffunction tags. The cffunction tags can have cfargument tags, but these are not required. Nothing else can be in this component other than these functions.

Some other component will include this interface component and basically have to create a function for each of the functions in the interface component. How this will be done is all theory to the community at the moment, but the theory will follow the steps above.

Now if my definition is correct, then this sounds more like something that would be useful at development time to make sure that a component being written follows certain rules. If it's going to be used at runtime, then it 'feels' like it would just be more overhead and unneeded validation. Am I wrong? Is there something I'm missing here? What are the issues and why should I (or anyone else) care?

What I want in CF 8 - part 1

There are TONS of great things inside Java that I'd love to see exposed and wrapped up nicely in ColdFusion. The RegEx functions are nice, but I want ALL of the RegEx options from Java. I can use Alagad to work with images, but a real CFIMAGE tag would be great(sorry Doug). A wait() function in place of using a CreateObject to call a java command (http://www.cflib.org/codeView.cfm?ID=959). All these things and more exist in Java, are used by ColdFusion programmers and should be exposed for all in the next release.

Actually, having the ability to create a function library that is part of ColdFusion directly rather than something that has to be either 'on page' or included might be nice. A CustomFunction directory like the CustomTag one.

More Entries

BlogCFC was created by Raymond Camden. This blog is running version 5.9. Contact Blog Owner
House of Fusion | ColdFusion Jobs @ House of Fusion | Fusion Authority