Skip to main content
Ben Nadel at cf.Objective() 2010 (Minneapolis, MN) with: Emily Christiansen
Ben Nadel at cf.Objective() 2010 (Minneapolis, MN) with: Emily Christiansen ( @egchristiansen )

Making My ColdFusion Tags More Consistent

By on
Tags:

The other day, I was looking through someone else's ColdFusion code and the order in which they defined some of their ColdFusion tag attributes was really getting under my skin. Something about it just seemed so illogical. As I was trying to process this frustration, I turned the magnifying glass inward and reflected on some of my own ColdFusion tag conventions. What I came to realize with disappointment was that my tag attributes were just as illogical, the only difference was that I was used to my own way of doing things.

I knew something needed to be done; I needed to find some sort of reason, some sort of methodology behind my tagging conventions - otherwise, I'm just a monkey at a computer. So, I thought to myself, "What is a ColdFusion tag doing?" And, what I realized was that most ColdFusion tags are really just providing different ways to set a variable. In a way, they are all variations of the CFSet tag:

<cfset x = y />

Here, we have our tag name, CFSet, then the variable we are creating or assigning value to, X, and then the value that is being assigned, Y. The next step up from this is a method-based CFSet tag:

<cfset x = f( y ) />

This adds an "action" to the equation, but it's basically the same thing: we have our tag name, CFSet, then the variable we are creating or assigning value to, X, then the action we are performing, F, and then an additional value required for this action, Y. If you think about it, isn't this latter equation what most tags are doing? As such, I have decided to change my tagging conventions to all follow the generic order:

<cfset VariableName = Action( AdditionalValues ) />

Or, to be expanded a bit in a tagging context:

  1. Variable Name
  2. Action
  3. Required Attributes
  4. Optional Attributes

For a lot of tags, such as CFFile, CFImage, CFThread, and CFHttp where I am used to putting the action before the variable name, there's definitely going to be a bit of an adjustment period. But, I think in the long run, having a unified naming convention is going to have a serious payoff in terms of readability and maintainability.

Using the tags I just mentioned, let's take a look at some examples:

<!--- Read in file contents. --->
<cffile
	variable="strFileData"
	action="read"
	file="#ExpandPath( './test.cfm' )#"
	/>

Notice that I am putting the variable name first, then the action, Read, then the required attribute, File.

<!--- Read in image contents. --->
<cfimage
	name="objImage"
	action="read"
	source="puppy.jpg"
	/>

Again, I am putting the variable name first, objImage, then the action to perform, Read, then the required attribute, Source.

<!--- Run thread. --->
<cfthread
	name="objThread"
	action="run">

	<cfset THREAD.Foo = "Bar" />

</cfthread>

<!--- Join thread. --->
<cfthread
	name="objThread"
	action="join"
	/>

Again, we are putting the name first, then the action.

<!--- Grab image. --->
<cfhttp
	result="objGet"
	method="get"
	url="http://some-image-domain.com/1517832_fef835681b_o.jpg"
	getasbinary="yes"
	useragent="FireFox"
	/>

Again, we are putting the name first, Result, then the action, Method, then the required attributes, URL and GetAsBinary, and then the optional attribute, UserAgent.

Some of this definitely feels awkward at first. For example, I am so used to putting the URL attribute first in my CFHttp tags that seeing it as the third attribute is a bit jarring. But I don't believe that awkwardness is a bad sign - I believe that the awkward feeling is my mind trying to cast off the chains of inconsistency. My bet is that after a week of doing this, it's gonna feel very natural and well thought out.

Want to use code from this post? Check out the license.

Reader Comments

29 Comments

I'm in the middle of writing a detailed Coding Standards/Best Practices document for my company. I'm definitely going to include this information. I've always wondered what the best way to list attributes was - most of the time sticking to alpha, or whatever came to me at the time - but, this makes a lot of sense. Thanks.

15,640 Comments

@Eric,

Always glad to share my thoughts. It's a bit startling when you begin to evaluate your own practices and realize that there's no rhyme or reason to them.

153 Comments

So it looks like you're doing subject - indirect object - verb - direct object? I tend more to subject - verb - indirect object - direct object when I code. But as long as you are consistent, that's cool.

My personal pet-peeve is the lack of consistency between YES/NO and TRUE/FALSE for attributes. Drives me crazy. I'm a TRUE/FALSE kind of guy, but I don't really care which it is, just frickin' pick ONE!

I just yesterday finally got around to installing the CF8 taglibs for HomeSite+ and literally the first thing I did was open up the VTM folder and do a global find and replace for YES:TRUE and NO:FALSE.

Except ... wtf is up with imageSetAntiAliasing(img, "on")? Like we needed a third set of options?

15,640 Comments

@Rick,

Can you give me an example of "subject - verb - indirect object - direct object", I am not sure I follow.

Yeah, I agree 100% with the true/false stuff. I believe with the GetAsBinary, you actually need to use Yes cause its not just yes and no, I think you can select Auto. But that being said, I started using true / false where ever possible the second it came out.

34 Comments

I'm not really sure that comparing a function evocation to tags for formatting is really a solid comparison. You can look at them and conclude the opposite reasoning as well. I mean, if you look at the <cfset /> tag, and then converted it to a function, you'd have an evocation that looked like set(x, f(y)). Looking at your file example, the a "translation" of the CF tag to a function call would be FileRead(file, "myfile.txt"). This indicates that your code should list the action first, variable second, and other params after that.

I personally list the variable I'm saving last, because the tag "reads" clearer. <cffile action="read" file="mytext.txt" variable="x"/> reads as "Read mytext.txt into x".

15,640 Comments

@Jon,

I see what you are saying, but I was not talking about turning the tag itself into a function; when I referred to "action", I was referring to the "F" method in the second CFSet example. Generically speaking:

<tag variable = action( arguments ) />

I did not mean to refer to "tag" as an "action". And, a lot of times, it's not - it's merely the context. Take File for example, CFFile is not the action - it's mere the context in which the action - Read, Write, Append, Delete - is being performed:

<tag data = Read( file ) />

As such, I am not sure your that parallel makes complete sense.

Now, when you say the tag "reads" better with the variable at the end, take a moment to really think about it - is that because of how you are used to doing it? Or is it because there is a real meaningful reason to having it at the end?

Remember, change always "feels" awkward at first, even when it is the right thing.

1 Comments

I've finished to keep one simple rule for any attributes/properties in any technology :
- coldfusion tags attributes,
- flex mxml tags attributes,
- OO class properties (as3/java...),
- sql table properties,
...

This simple rule is "alphabetical order"!
It works great, easy to understand and to read for anybody.

33 Comments

Incoming rant...

Does it really matter?

I've never worked at a company where they have even remotely rigid code conventions and I can't imagine ever doing so. Does it really make a difference if I don't always put attributes in the same order for the same tag?

Try implementing something like this with a development team of even only a few developers and you'll probably give the idea up pretty quick. Developers are creative. We all have our own style. In one of my last companies, even without comments I could tell who wrote a particular function just by looking at the style of their code; where they put their braces, how they names their local variables, etc. Why would you want to take that away?!

We're programmers! We're here to be creative and write code, not obsess over the order of attributes, whitespace and variable naming conventions!

Just my €0.02!

George.

15,640 Comments

@George,

Rebounding rant.... :)

I am not talking about working on a development team; I am referring to my own integrity. At the end of the day, it is important to me that my code follow well thought-out guidelines that have meaning. To me, that is beautiful. To me, that is worthy of having time put into it.

Remember, every line of code that I write is a reflection of myself and my underlying character. Everything that I do, every action that I take is an extension of myself - to separate one from one's work is foolish and is not how people are truly perceived. And, when I can sit down and explain to myself that I format my code for this reason and I order my attributes for this reason, and I name my variables for this reason, then I feel that I have simply created an extension of the integrity that I practice in other aspects of my life.

All to say, this is a personal feeling; the title of the blog post was about making my tags more consistent, not the tags of anyone else.

15,640 Comments

@George,

This discussion made me think of the Peaceful Warrior, and I think it's very appropriate. If you are not familiar with the movie, I have several posts about it ( bennadel.com/index.cfm?dax=blog:1454.view ). In the movie, the wise man, Socrates, is at a table eating with Danny, the gymnast. Danny is eating wildly, Socrates is eating peacefully, savoring each bite.

They talk and the conversation leads:

"That's the difference between us Dan: you practice gymnastics, I practice everything."

I keep thinking about this when I think about the comments you made. Something about it strikes so deep in me. And I think to myself: Am I a person who wants to practice "getting a job done"? Or am I a person who wants to practice getting all aspects of a job done correctly?

I have to say, I am not the latter yet, you better believe I am gonna do whatever I can do make sure I get there eventually.

92 Comments

I'm okay with all of these changes except for you putting trailing slashes on your unclosed CF tags (cfset, cfqueryparam, etc).

It's UTTERLY unnecessary and it just irritates the bejeezus out of me. ColdFusion is NOT HTML code and shouldn't be treated as such.

8 Comments

@andy,

I'm sorry but I have to disagree with you. Not fundamentally, but, for the reason I'll explain below.

For me it is easier to read code that has self-closing stand-alone tags.
So, when I'm looking at:

<cfif someConditions EQ true >
<cfset somevar = 'a value' />
<cfset doSomthingTo(somevar) />
</cfif>

I can see the sets very clearly because they close and the logic constructs like cfloop and cfif because they don't.

It's all personal taste and style right?

That's just one of my 15 pieces of flare. :-)

49 Comments

I have two different pieces of information to add to this, so I'll split my response into two parts.

Part 1:

I have to say that I'm on board with Jon. The tags definitely read better when laid out "verb subject object" style - it more naturally follows the conventions of spoken enlish. The goal of any code should be to read as close to your native spoken language as possible. That makes it much easier to understand if it's not your code, and much easier to maintain if it is.

Think about if you were publicly speaking about your code, or even discussing it with another developer on your team. What sounds more natural - "read the file into the variable", or "take the variable and read the file into it"?

Let's frame it another way - suppose you were to outline your code, or to write pseudo code. What reads more naturally:

if file exists
read file into variable
manipulate variable
save variable to file

Or this:

if file exists
variable is assigned result of reading file
variable is manipulated
variable is saved to file

Now as a disclaimer, if you were writing in some languages (some of the functional ones come to mind), the second form is closer to what you would write in code, and may in fact make more sense to you. But I think we can all agree that the first version generally reads easier.

What is more important to the logical flow in the abstract, high-level sense - the fact that a file is being read, or the fact that a variable is being used?

---------------

Part 2:

If you still disagree, just head to the source itself - the CF documentation. If you read the docs, you will see that the tags generally follow the format suggested above by Jon and myself. And I don't think that's an accident. Reading from the docs, you generally see this:

CFFILE action=""
CFIMAGE action=""
CFTHREAD action=""
CFFEED action=""

And here's a subtle but important point - most of the tags in CF already have an *implied* action (invoke, execute, output, object, query). These tags generally take the subject of the action as the first attribute. So if you want to remain consistent with those tags, you'd want to maintain "action subject" prhasing. Examples:

CFOBJECT component=""
CFEXECUTE name=""
CFINVOKE component=""
CFOUTPUT query=""

Also, if you think about it logically, for the tags that require an action parameter, the action parameter really denotes a separate logical operation. For example, cffile action="read" has different attributes entirely than cffile action="write". And I'm betting that under the covers in the CF source, each action is logically separated into either its own function, or into it's own block-level operation.

Let's do a really extreme contrived example(tm) just to illustrate a point. What if the CF designers had decided to just lump all of these into one tag instead. These could be written like so:

CFFOO action="object" component=""
CFFOO action="execute" name=""
CFFOO action="invoke" component=""
CFFOO action="output" query=""

What's more important here, the first paramter or the second? Which parameter controls the behavior of the tag, and thus has different logical meaning?

1 Comments

@Chris...

The thing is though, with well formed code, the two cfset lines would be indented, PLUS you already know that cfset is a single line tag. So while your concept might be sound, your specific example is not.

Anyway...it IS a matter of personal preference, but it just doesn't make sense.

15,640 Comments

@Andy,

I like the self-closing tag, but people can go either way on that. The only place where it is not acceptable is for tags that have an optional closing tag (ex. CFModule, Custom tags, CFHttp). In that case, having a single tag that doesn't self close can be very misleading, especially if the given programmer has questionable formatting and tabbing (not that uncommon in code I have seen). But, for the rest of the tags that cannot possibly have closing tags, I don't think it makes too much of a difference.

@Roland,

I am not sure that regular code can be compared to spoken or pseudo algorithms. Those concepts are meant to abstract and simplify ideas. You might have a line of pseudo code that says:

"Read file in and parse into CSV"

That may, in reality represent many lines of code. To draw parallels between the simplicity of one and the simplicity of another might be a slippery slope. Pseudo code represents ideas, not so much implementation.

To look at an example of this, if you were to talk about a query, you might say, "Get all the contacts from the database and cache the data". However, when we write out the CFQuery tag, we generally do this:

<cfquery name="contacts" datasource="##">...</cfquery>

In an entire application, the "Datasource" is really not an important attribute as it probably never changes. As such, the name comes first because it is really the only meaningful attribute. If you were to translate this to "English", it would be:

"Store into the variable 'contacts' the value of the following query for contacts".

All to say, when you ask:

What is more important to the logical flow in the abstract, high-level sense

... I say that the two different contexts (pseudo code, actual code) have different purposes so it's not an either-or, it's a logical flow in this case, high-level sense in that case.

As far as your other examples, I don't use most of those tags, so I'll pick the one that I do use:

CFINVOKE component=""

I assume what you are saying here is that you put "component" first because it has a different behavior than "webservice" correct? But I ask, if we are getting a value back, what difference does it make? Both methods are storing values into a variable - the means by which you get that values seems secondary to the fact that it is being returned.

<cfinvoke returnvariable="" component="" method="" />

<cfinvoke returnvariable="" webservice="w" />

... What IF, all I showed you was this:

<cfinvoke returnvariable="" .... />

What would you feel? Would you be totally lost? Would you have no idea what was going on? Take a minute to think. I am guessing you won't feel lost or concerned at all because you will see at a high level that, "Oh, we are getting data using cfinvoke and storing it in this variable." Isn't that what all CFSet statements are? This is not a feeling that we have to fight, rather I think it is a feeling we should embrace.

To follow another extreme contrived example (tm) :) link about the two methods ListFind() and ListContains(). These are two *very* different methods with very different intentions. Following your logic above, that would mean that we'd put the method first since it defined the "black-boxed" behavior of the method:

<cfset ListFind( list, value ) => returnVariable />
<cfset ListContains( list, substring ) => returnVariable />

Does it seem silly when we write it that way? I think so. But what about when we write it this way (with made-up tags):

<cflist action="find" list="#list#" value="#value#" returnvariable="" />

<cflist action="contains" list="#list#" substring="#substring#" returnvariable="" />

I bet that feels more natural than the CFSet tags before it, right? Even though those examples are made up. But why? Is it because it is the correct way to do it? Or is it simply because that is the way you are used to doing it and it just feels comfortable.

As a final note, with all the people that complain about how crappy the live docs are, I am not sure we should defer to them for any logic :)

15,640 Comments

@Benoit,

In CSS, I am all about the alphabetical ordering because there is no given property rule that has any more "meaning" than another within a given rule. As such, alpha-ordering is the only thing that can make sense. However, in ColdFusion, I feel that the different attributes have inherently different meanings and I therefore I treat them in a different way.

49 Comments

@Ben

You touch on the "non-important" attributes being at the tail end of the tag. This is an important thing to note, and is kind of the point I was trying to get at. This is especially important to consider in the tags that we are talking about. All of the tags that have the action="" attribute have different sets of required and optional attribtues depending on the action being performed.

The entire *meaning* of the tag changes based on the value of the action attribute. Thus cffile action="write" and cffile action="read" have entirely different meanings. You can't separate the action from meaning and indeed from the operation of the tag, and you shouldn't.

In your response, you used cfinvoke as an example.


... What IF, all I showed you was this:

cfinvoke returnvariable="" .... /

What would you feel? Would you be totally lost?

Of course not, but that's because cfinvoke has an *implied* action. You simply don't need to specify the verb. Cfinvoke implies that you'll be calling a function or an external object and retrieving a result.

Let's look at a tag that requires an action though - cfimage. To borrow from your example, what if all I showed you was this:

cfimage name="img"

Would you be totally lost? I'm betting you would. What did that cfimage tag *do*? Did it read it from disk? Did it add a border? Did it resize? Who knows. There's simply no way of knowing without the context of the action.

To put it another way, the tag itself is really "cfimage action=read", not just cfimage. Cfimage has zero meaning without its action attribute, and the two should not be separated because of this. The action is clearly the most important aspect of the tag.

15,640 Comments

@Roland,

Ok, maybe "non-important" attributes is not the right way to say it. I am not sure what the best way would be.

As far as:

<cfinvoke returnvariable="" .... />

... you are correct, it does imply that you are retrieving a value from a method or an external object because that those are the possible values of that context. However, is this really any different than this:

<cfimage name="objImage" .... />

This simply implies that you are storing a ColdFusion image object into that variable because any CFImage tag that uses name must imply that. It does not, howver, impy anything about where that image is coming from or what is being done to it just as CFInvoke implicitly implies nothing about where the data is coming from or what is being done to it (other than the simple fact that data is being returned).

49 Comments

And that's exactly my point - the fact that CF is storing the image in the variable isn't at all important. What CF is doing to the image *before* it stores it in the variable is the important part. The action that's being performed *is* the logical flow of your code. The variable name has nothing to do with that. You could easily change the name of the variable and have absolutely zero impact to what your code does. But if you change the action, the entire operation of your code changes.

49 Comments

Sorry - hit reply too soon.

What I'm getting at is that cffile or cffimage in and of themselves do *not* in fact imply that anything is occurring and cannot be separated from their actions.

Getting back to your earlier examples with functions, of course I would not write this code:

ListFind( list, value ) => returnVariable

I would obviously write:

returnVariable = ListFind( list, value )

But look at the name of your function. ListFind - you have encoded the name of the tag *and* the action into the function name. So of course it makes sense that if you were to convert it to a tag, it would be written: "cflist action=find", precisely because that is equivalent in phrasing to ListFind.

That's why cffile action="read" is written FileRead and cffile action="write" is written FileWrite as functions.

By your logic, would you write it like this:

List returnvariable Find(list, value)?

That's equivalent to what you're doing the way you're writing tags in the blog post.

15,640 Comments

@Roland,

I think I see the fundamental difference in the way we are seeing the issue:

the fact that CF is storing the image in the variable isn't at all important. What CF is doing to the image *before* it stores it in the variable is the important part.

To me, the storage of the data and the source of that data of fundamentally equal importance. Take for example, the file read. In the greater scheme of things, I don't really care about the file read - what I really care about is that data moves into a variable that I then want to process in further ways. So, in fact, the storage of the data into the variable is more essential to the greater flow of the algorithm than the source of the data itself.

But, perhaps we are just thinking about this too differently to come to any agreement.

15,640 Comments

@Roland,

On the walk home, I had a thought that's worth examining - what if the CFSet tag worked with attributes rather than stand-alone values. For example, what if it worked like this:

<cfset name="Foo" value="Bar()" />

I think, if we follow your reasoning, then really, you would prefer to write the tag as such:

<cfset value="#Bar()#" name="Foo" />

Now, perhaps you will say that because the purpose of the CFSet tag is to store values, then actually in that case, the name attribute would come first. To this, I would ask, is the purpose of the CFSet tag primarily to store values?

This is an interesting question. If we think about the attributes in this tag, are they both required? No - as in the standard CFSet tag, the name of the variable is actually optional, only the value is required:

<cfset value="#ArrayDeleteAt( arr, 1 )#" />

So, as it seems, the required action of the CFSet tag is to execute a command; storing the result of the execution into a variable is of secondary concern.

Thoughts?

For me, I would definitely be putting the name attribute first, but I want to see how you see this.

49 Comments

First off, I want to say that I'm very much enjoying this debate - I think there are great points on both sides, and that it's a great thought exercise. :)

Before I answer the cfset question, let me try one last tack to see if it better explains where I'm coming from on this. Some of my habits are admittedly so ingrained that it's been difficult to characterize why I'm defending them. But I think now I have a beter explanation than I've had so far.

So my day to day is actually only about half ColdFusion. I use a ton of .NET, and before that Java, and before that C++. I have used all of these in the context of integrating other systems and technologies with CF. So from day one with CF, I've also used a ton of other langauges, most of them supporting some level of object orientation or class library. (As a side note, the .NET integration in CF is the best thing that ever happened to me, but that's a different story...)

I don't consider cffile to be an "operation" as I think you do. You see cffile, and you think "hey - we're doing a file operation". When I see cffile, I see a class library. Just because there is a cffile tag doesn't mean that an operation is implied. So when I see cffile, it looks more to me like a class or an object would. So in my head, this is cffile:

class cffile
public any read(string filePath)
public void write(string filePath, any value)
public void copy(string filePath, string destination)
public array readBinary(string filePath, integer length)

This is how I see cfimage:

class cfimage
public struct info(string filePath)
public image read(string filePath)
public image resize(image originalImage)

So when I see a cffile tag, what I really see in my head is this:

cffile.read(filePath)
cffile.write(filePath, data)

To me, the "action" attribute is the function, and the tag itself is really just a class library or an object. As such, they are inseperable. They cannot be separated, or they lose all of their functionality, and indeed all of their context.

Now on to cfset ....

Given the above, there are two ways to look at this. First off, if you look at it as I have framed it from a library standpoint, then you have two options for returning a value. You either return a value, or you update a buffer or an out parameter.

If we're approaching it from the standpoint of most closely matching the way the tags are writen, you would pass in a variable to handle your result, or use a buffer.

In C++, I would think of that something like this:

class cffile
public void read(string filePath, string* output)

(This would be a byref value in .NET instead of a pointer)

When you call it, you would pass in a buffer to hold the results. So your code would basically look like this:

string* output
cffile.read(filePath, output)
print(output)

This is the way that I think most closely models the way that tags work. They don't really have the concept of return values - you give them the name of a buffer in which to store your result. But the important part here is that the action, or the function, is still not separate from the class.

The other way to look at it is as if the operation is using return values. In this case, it would look like this:

class cffile
public string read(string filePath)

In your code you would use it like this:

output = cffile.read(filePath)

Note that the function is still attached to the object even though we're using left-hand assignment for the result. So still, cffile and the action or function (read) still need to be written together.

I think that what's important in this operation is the order of evaluation. The right-hand side is evaluated first. So the order of evaluation is still: perform the operations on the right-hand side, and then do something with the result. Just becuse the target of the assignment is on the left side, this does not make the assignment the more important operation. The operation that is evaluated first, and is thus the more imporant of the operations is still on the right-hand of the operator.

Now to directly answer your question about cfset . . . I think you answered it already in your example. Storing the result is an optional operation. Therefore, the "name" or the result parameter is an optional parameter. That means that it has lower precedence. To me, that means that it belongs last in the list of attributes. So yes, if I were designing cfset, it would look like this:

<cfset value="#Bar()#" name="Foo" />

Whew - that was a lot of typing after 2 beers. I hope that what I wrote made sense :)

76 Comments

Couldn't be bothered reading all the comments :p
But nice post Roland - I think that pretty much covers it imo

15,640 Comments

@Roland,

I can see what you're saying so far as viewing the tag as a sort of static class and the action's being methods on that static class. And, perhaps this is just not something we can agree on. You see the tag as a direct object, I see it as a context:

// Define File class.
function File(){}

// Define static method on file class.
File.prototype.Read = function( strPath ){
. . . . return( "file data here" );
}

// In context of static class, call method and assign value.
with( new File() ){
. . . . fileData = Read( "C:\....." );
}

// Alert file data.
alert( fileData );

I don't think we are going to come to terms on this :)

15,640 Comments

@Roland,

Also, on a final note, even if we did consider the idea of passing a buffer around such as in your example:

public void read(string filePath, string* output)

I don't do a whole lost of C++, mostly Java in the context of ColdFusion. And, in that context it is REALLY hard to find methods that actually take a string buffer as one of several arguments. The only one I could find was the Java Pattern Matcher. The Pattern Matcher does write to a buffer with its AppendReplacement() method:

AppendReplacement( StringBuffer, String )

Here, you can see that the target of the assignment is actually the first argument, not the second, and the data to be assigned is the second. So, it would seem that in Java, even if you want to utilize the buffer internally to a class method, it still is given priority over the data that is being assigned. That is why I do not think your Read() example makes the most sense. All to say, I still think assignment is an equally important function in parallel to the class action being taken.

26 Comments

@George Bridgeman,

I'm with George. We get paid to write code not to sit around and have some sort of academic circle jerk meets totalitarian S & M over _EXACTLY_ how the code looks (I'd find tamer words but that would seem to be bit of disservice when posting a comment at Kinky Solutions).

When we look at how much man of us are getting paid, one has to wonder how getting hung up on something as unimportant as attribute order is worth an extra $100 here or there just to get things sorted out exactly per some some standard. Exactly what is gained by an extra, let's say, $250 dollar a month being spent making sure attributes exist in some specific order?

I would argue absolutely nothing of value is generated. Someone feels good they did something "productive" by making sure it was part of some best standards and some others get to grumble about how bob or cynthia keep writing code that doesn't follow the best standards. But nothing comes from it that is actually add value for the customer.

I know, I know... some folks will say it's easier than maintain. Really? You're telling me that women and men that can tackle working with complex CF applications are somehow slowed down because the name attribute didn't come first in a tag. Like "oh crap, I've used the cfinput tag before but hell if I know how it works with the name attribute is listed 4th".

Now we all have our preferences. And sure it's nice to be consistent. I used to think it was a big deal to have best practices that included things like this in them. Maybe I've hit my head one too many times but these days it feels a bit like a bunch of teetotalers forcing through prohibition. No matter how well intentioned it is, it will never actually work. And it forces a specific view point on others, one that is essentially subjective.

After all, if having perfectly uniform code produced value why aren't we all using a fancy code beautifier to fix up all are ColdFusion code? Surely after what? 12-13 years of CF if it was so valuable to do we'd have a tool to it with.

15,640 Comments

@Allen,

First of all, I am not sure why you think it will take more money to produce code that adheres more to my own standard if I am the one writing the code? I don't think it will take any extra time. If anything, I think it will take less time as there is less ambiguity as to how tags should be defined. Remember, these are not random tags - these are a finite set of tags; and, just like any other repetitive task, it should become second nature quite quickly.

I also think that it will add value because the "setting" nature of the code (ie. that it defines how values are being set into variables), it will make the code easier to follow as the life cycle of variable data will be easier to follow (always the first tag attribute rather than having to visually parse a tag looking for the result, or variable, or name attribute, not even sure if it exists). Now, if the variable set is NOT the first tag, I immediately know that this tag result is not being stored and is therefore not going to be used later on. This is a really nice optimization, at least in my experience.

>> No matter how well intentioned it is, it will never actually work.

When you say it will never work, what are you talking about? I am not sure what about this can be considered to work or not work?

>> And it forces a specific view point on others, one that is essentially subjective.

I am not sure what you are referring to here? I am talking about making my OWN code more consistent; at no point did I mention about forcing other people to follow this standard.

16 Comments

This topic surprised me. I simply do thing in [TYPE][Alphabetical Order].

For example: In a CSS file, I will group all classes together and list them in alphabetical order. Inside a ColdFusion tag, the grouping is not required so the attributes are listing in alphabetical order.

Simple and logical (at least I think so).

1 Comments

Can you give me an example of "subject - verb - indirect object - direct object", I am not sure I follow.

Yeah, I agree 100% with the true/false stuff. I believe with the GetAsBinary, you actually need to use Yes cause its not just yes and no, I think you can select Auto. But that being said, I started using true / false where ever possible the second it came out.

153 Comments

Well, let me stop and reiterate definitions for each of those grammatical terms.

Subject: The focus of the sentence.
Verb: The action of the sentence.
Indirect Object: The thing upon which the subject and verb are acting.
Direct Object: The recipient of the action performed on the Indirect Object; "to whom" or "for whom".

Different tags have different connotations. Some are implicitly verbs, such as cfset, while others are implicitly subjects, such as cffile. However, Ben's post was primarily about the latter case, so that's what I was referring to:

Subject: tag name, such as cffile.
Verb: action attribute - what do you want me to do with the subject?
Indirect Object: file or source or similar attribute - what's the action acting with or on?
Direct Object: variable or destination or similar attribute - where do the results of the action end up?

English is generally: subject, verb, direct object, indirect object.

"[Rick] [posted] [a comment] on [Ben's blog]."

So, if we were to follow that same order in tags:

But, it's just as valid to go: subject, verb, indirect object, direct object. This is often use to eliminate prepositions.

"[Rick] [sent] [Ben] [an email]."

In this case in CF tags, you'd swap the last two attributes (file and variable).

Personally, I try to code more toward the latter case (IO then DO) as when I come back through the code later the IO is almost always the more important thing -- that is, where the result went is more important than what went into making it.

But that's just me.

15,640 Comments

@Rick,

I don't think I follow the analogy. Doesn't that mean that the CFSet tag should somehow be reversed? Something like:

<cfset x --> y />

Where "CFset" is "storing" "x" into "y"?

It seems like the most foundational tag in ColdFusion wants to go against your Subject-Verb-IO-DO analogy.

153 Comments

The problem with cfset is that there are only 3 of the 4 components. You can think of it as either an implied verb or an implied noun:

<cfset y=x>

translates as:

"cfset [stored] y from x" -- implied verb
or
"[cfset] set y from x" -- implied subject

Admittedly, the second seems like a bit of a redundant stretch, but it keeps more with the previous theme of the tag being the subject, such as cffile.

So, knowing that, we're left with IO and DO. The DO is the thing upon which the subject/verb/tag acts, while the IO is the recipient of that action.

I think the tricky thing here is that you want to think of cfset as performing its function on the left side, right? But that's not the case -- all of the action really happens on the right and the left side is just a byproduct.

Hence why you can do <cfset foo()>, which might translate as "[cfset] [ran] [the function foo]" -- Subj-Verb-DO. You can't have an IO without a DO, and you can't have a left side without a right side. But you can have a right side without a left side and a DO without an IO.

So ... the right hand side is the DO, as that's where all the action happens, and the left-hand side is the IO, as that's the recipient of the action.

So, yes, cfset is Subj-IO-DO.

(And keeping with my point above, the IO or recipient is more interesting than what goes into it, and is thus on the left and foremost visually.)

15,640 Comments

@Rick,

I have to be honest - my brain is so fried right now from class that I can't follow along. I am not sure if we are agreeing or disagreeing :) I have a bad case of brain-hurt :)

I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel