Friday, 17 August 2012

Quality of CFML documentation

[This is a "toned-down" edit of the first draft I made of this doc.  The initial doc had a bit more vitriol in it than would be considered helpful.  Plus I was going to have to give it an NC-17 rating for its language.  It's a good thing to draft something then cool-off before pressing "send" sometimes]

G'day:

I've had a long day, some things that could gave gone smoothly didn't, and I'm in an intolerant mood. Some would say "sounds pretty much like your default setting, Cameron". Fair cop.

Anyway, I'm trying to write this second article about ColdFusion arrays (now complete... I started on this rant a few days ago), and I'm reading the official Adobe docs for inspiration (OK, not "inspiration", I guess. Anyway: I'm reading their docs).

Thursday, 16 August 2012

Arrays in CFML (part 2)

G'day:
In this article, which is part two in an ongoing series, I'll discuss the various functions CFML ships with for working with arrays. The first part described what an array is, and how to create them.

The online docs cover each of these functions too, but the coverage is pretty superficial. They cover all the syntax options and give a code example, but they don't go beyond that. Having been around the block a few times (and thus... err... ending up back where I started.. hmmmmm...), I've picked up the odd but of insight, and have explored some of the idiosyncrasies of CFML that isn't covered in the docs. I shall try to discuss why one might want to use a given function, rather than just cataloguing that it exists (which is all the official docs seem to set out to do, at times).

The docs are good for something though: they do act as a good lookup of what's available, so go have a look at then after yer done here.

Anyway, enough waffle...

Just giving my surveys a nudge

G'day:
A few weeks back I launched a coupla surveys on Survey Monkey (what a cool service that is... I'd never used it before).

I've got a reasonable number of responses, but my blog was / is so low-traffic that I haven't accumulated a number of responses I think makes a legit case to pass on to Adobe.

Sorry to pester y'all, but if you haven't done the surveys, I'd deeply appreciate it if you could.

Here they are:

Much appreciated.

--
Adam

Wednesday, 15 August 2012

CFML: More on Application.cfc... when things run

G'day
This one stemmed from me trying to come up with an accurate answer to someone's question on StackOverflow.  To summarise, the question was about what order things run in, what scopes come into play when, and all that sort of thing.  Stuff I imagine most of us pretty much know, but perhaps don't completely know the boundaries of the edgecases.  Certainly I sat down at the keyboard, drew myself up in an all-knowing sort of way ready to type the model answer, before thinking... "you know what?  I don't actually know for sure".  And when I answer stuff on forums, I like to be like 99% confident I'm right.  Not for my sake, but because I don't like wasting people's time by giving inaccurate answers.  And a bit for my own sake ;-)


Anyway, I voted-down the two answers that were there when I first read the question, because I thought they were - on balance - inaccurate.  Both had elements of correctness about them, but they both had blatant inaccuracies about them too (ie: they stated things that were outright wrong).  But I figured if I was voting stuff down, I had better come back with the goods.
Speaking of StackOverflow... here's an aside.  If you are reading this and you don't already help out on StackOverflow and - more importantly - the Adobe ColdFusion forums, please consider donating some of your time to helping the ColdFusion community.  There are a lot of people asking questions out there, and not enough people to answer them.  We could use your help.
But anyway... that's not the topic of my wittering for the day.
Application.cfc.

So, yeah, it occurred to me I didn't actually 100% know when various scopes became available, and what was available where, and that sort of thing.  I also saw it as low-hanging-fruit for a blog entry, so here I am now.

I knocked together a quick Application.cfc, which logged what it was up to and when:


The logic at play in this is repetitive: at each step of the Application.cfc I test various scopes that might exist, report if they do exist, and attempt to create a variable in them.  Then as processing continues through various event handlers, I keep track of what exists and where.

The log file created is as follows (this is a bit longwinded... scroll down rather than read it all. I've highlighted the important bits):

1 in pseudoconstructor before application name is set application scope not enabled
1 in pseudoconstructor before application name is set session scope not enabled
1 in pseudoconstructor before application name is set request.pseudoconstructor initialised
1 in pseudoconstructor before application name is set this.pseudoconstructor initialised
==================================================
1 in pseudoconstructor after application name is set application scope not enabled
1 in pseudoconstructor after application name is set session scope not enabled
1 in pseudoconstructor after application name is set request.pseudoconstructor existed
1 in pseudoconstructor after application name is set this.pseudoconstructor existed
==================================================
1 in onApplicationStart application.pseudoconstructor initialised
1 in onApplicationStart session scope not enabled
1 in onApplicationStart request.pseudoconstructor existed
1 in onApplicationStart this.pseudoconstructor existed
==================================================
1 in onApplicationStart application.onApplicationStart initialised
1 in onApplicationStart session scope not enabled
1 in onApplicationStart request.onApplicationStart initialised
1 in onApplicationStart this.onApplicationStart existed
==================================================
1 in onSessionStart application.pseudoconstructor existed
1 in onSessionStart session.pseudoconstructor initialised
1 in onSessionStart request.pseudoconstructor existed
1 in onSessionStart this.pseudoconstructor existed
==================================================
1 in onSessionStart application.onApplicationStart existed
1 in onSessionStart session.onApplicationStart initialised
1 in onSessionStart request.onApplicationStart existed
1 in onSessionStart this.onApplicationStart existed
==================================================
1 in onSessionStart application.onSessionStart initialised
1 in onSessionStart session.onSessionStart initialised
1 in onSessionStart request.onSessionStart initialised
1 in onSessionStart this.onSessionStart existed
==================================================
1 in onRequestStart application.pseudoconstructor existed
1 in onRequestStart session.pseudoconstructor existed
1 in onRequestStart request.pseudoconstructor existed
1 in onRequestStart this.pseudoconstructor existed
==================================================
1 in onRequestStart application.onApplicationStart existed
1 in onRequestStart session.onApplicationStart existed
1 in onRequestStart request.onApplicationStart existed
1 in onRequestStart this.onApplicationStart existed
==================================================
1 in onRequestStart application.onSessionStart existed
1 in onRequestStart session.onSessionStart existed
1 in onRequestStart request.onSessionStart existed
1 in onRequestStart this.onSessionStart existed
==================================================
1 in onRequestStart application.onRequestStart initialised
1 in onRequestStart session.onRequestStart initialised
1 in onRequestStart request.onRequestStart initialised
1 in onRequestStart this.onRequestStart existed
==================================================
1 in onRequest application.pseudoconstructor existed
1 in onRequest session.pseudoconstructor existed
1 in onRequest request.pseudoconstructor existed
1 in onRequest this.pseudoconstructor existed
==================================================
1 in onRequest application.onApplicationStart existed
1 in onRequest session.onApplicationStart existed
1 in onRequest request.onApplicationStart existed
1 in onRequest this.onApplicationStart existed
==================================================
1 in onRequest application.onSessionStart existed
1 in onRequest session.onSessionStart existed
1 in onRequest request.onSessionStart existed
1 in onRequest this.onSessionStart existed
==================================================
1 in onRequest application.onRequestStart existed
1 in onRequest session.onRequestStart existed
1 in onRequest request.onRequestStart existed
1 in onRequest this.onRequestStart existed
==================================================
1 in onRequest application.onRequest initialised
1 in onRequest session.onRequest initialised
1 in onRequest request.onRequest initialised
1 in onRequest this.onRequest existed
==================================================
1 in onRequestEnd application.pseudoconstructor existed
1 in onRequestEnd session.pseudoconstructor existed
1 in onRequestEnd request.pseudoconstructor existed
1 in onRequestEnd this.pseudoconstructor existed
==================================================
1 in onRequestEnd application.onApplicationStart existed
1 in onRequestEnd session.onApplicationStart existed
1 in onRequestEnd request.onApplicationStart existed
1 in onRequestEnd this.onApplicationStart existed
==================================================
1 in onRequestEnd application.onSessionStart existed
1 in onRequestEnd session.onSessionStart existed
1 in onRequestEnd request.onSessionStart existed
1 in onRequestEnd this.onSessionStart existed
==================================================
1 in onRequestEnd application.onRequestStart existed
1 in onRequestEnd session.onRequestStart existed
1 in onRequestEnd request.onRequestStart existed
1 in onRequestEnd this.onRequestStart existed
==================================================
1 in onRequestEnd application.onRequest existed
1 in onRequestEnd session.onRequest existed
1 in onRequestEnd request.onRequest existed
1 in onRequestEnd this.onRequest existed
==================================================
1 in onRequestEnd application.onRequestEnd initialised
1 in onRequestEnd session.onRequestEnd initialised
1 in onRequestEnd request.onRequestEnd initialised
1 in onRequestEnd this.onRequestEnd existed
==================================================
2 in pseudoconstructor before application name is set application scope not enabled
2 in pseudoconstructor before application name is set session scope not enabled
2 in pseudoconstructor before application name is set request.pseudoconstructor initialised
2 in pseudoconstructor before application name is set this.pseudoconstructor initialised
==================================================
2 in pseudoconstructor after application name is set application scope not enabled
2 in pseudoconstructor after application name is set session scope not enabled
2 in pseudoconstructor after application name is set request.pseudoconstructor existed
2 in pseudoconstructor after application name is set this.pseudoconstructor existed
==================================================
2 in onRequestStart application.pseudoconstructor existed
2 in onRequestStart session.pseudoconstructor existed
2 in onRequestStart request.pseudoconstructor existed
2 in onRequestStart this.pseudoconstructor existed
==================================================
2 in onRequestStart application.onApplicationStart existed
2 in onRequestStart session.onApplicationStart existed
2 in onRequestStart request.onApplicationStart initialised
2 in onRequestStart this.onApplicationStart existed
==================================================
2 in onRequestStart application.onSessionStart existed
2 in onRequestStart session.onSessionStart existed
2 in onRequestStart request.onSessionStart initialised
2 in onRequestStart this.onSessionStart existed
==================================================
2 in onRequestStart application.onRequestStart existed
2 in onRequestStart session.onRequestStart existed
2 in onRequestStart request.onRequestStart initialised
2 in onRequestStart this.onRequestStart existed
==================================================
2 in onRequest application.pseudoconstructor existed
2 in onRequest session.pseudoconstructor existed
2 in onRequest request.pseudoconstructor existed
2 in onRequest this.pseudoconstructor existed
==================================================
2 in onRequest application.onApplicationStart existed
2 in onRequest session.onApplicationStart existed
2 in onRequest request.onApplicationStart existed
2 in onRequest this.onApplicationStart existed
==================================================
2 in onRequest application.onSessionStart existed
2 in onRequest session.onSessionStart existed
2 in onRequest request.onSessionStart existed
2 in onRequest this.onSessionStart existed
==================================================
2 in onRequest application.onRequestStart existed
2 in onRequest session.onRequestStart existed
2 in onRequest request.onRequestStart existed
2 in onRequest this.onRequestStart existed
==================================================
2 in onRequest application.onRequest existed
2 in onRequest session.onRequest existed
2 in onRequest request.onRequest initialised
2 in onRequest this.onRequest existed
==================================================
2 in onRequestEnd application.pseudoconstructor existed
2 in onRequestEnd session.pseudoconstructor existed
2 in onRequestEnd request.pseudoconstructor existed
2 in onRequestEnd this.pseudoconstructor existed
==================================================
2 in onRequestEnd application.onApplicationStart existed
2 in onRequestEnd session.onApplicationStart existed
2 in onRequestEnd request.onApplicationStart existed
2 in onRequestEnd this.onApplicationStart existed
==================================================
2 in onRequestEnd application.onSessionStart existed
2 in onRequestEnd session.onSessionStart existed
2 in onRequestEnd request.onSessionStart existed
2 in onRequestEnd this.onSessionStart existed
==================================================
2 in onRequestEnd application.onRequestStart existed
2 in onRequestEnd session.onRequestStart existed
2 in onRequestEnd request.onRequestStart existed
2 in onRequestEnd this.onRequestStart existed
==================================================
2 in onRequestEnd application.onRequest existed
2 in onRequestEnd session.onRequest existed
2 in onRequestEnd request.onRequest existed
2 in onRequestEnd this.onRequest existed
==================================================
2 in onRequestEnd application.onRequestEnd existed
2 in onRequestEnd session.onRequestEnd existed
2 in onRequestEnd request.onRequestEnd initialised
2 in onRequestEnd this.onRequestEnd existed


The log here follows two consecutive requests (labelled "1" and "2" in the leftmost column).

There's a whole lot of bumpf there, but the stand-out things are highlighted.

First, let's look at what happens in the pseudo-constructor (the bit of code within the component tags, but outwith any method in the CFC).

This is not surprising:

1 in pseudoconstructor before application name is set application scope not enabled
1 in pseudoconstructor before application name is set session scope not enabled

There's no chance that there'd be any sense of application before the this.name line had been encountered.  CF doesn't know which application a given request is part of before it's been told.  Equally the session scope cannot exist prior to the application being identified, because sessions are bound to applications.

This is straight forward:
1 in pseudoconstructor before application name is set request.pseudoconstructor initialised
1 in pseudoconstructor before application name is set this.pseudoconstructor initialised

Obviously we know we can set this-scoped variables here... we'd not be able to set the application settings otherwise.  Being able to set request-scope variables is slightly surprising, given that this is before onRequestStart(), esp. given what I'm drawing your attention to next:

1 in pseudoconstructor after application name is set application scope not enabled
1 in pseudoconstructor after application name is set session scope not enabled

So this is after the application has been named.  But still the application and session scopes aren't available.  I expected they might have been as there's no reason for them not to.  I guess CF waits until the onApplicationStart() and onSessionStart() event handlers start before starting those two scopes.  Given my earlier diatribe on events vs event handlers, I half expected the scopes to be there, even if the event handlers had yet to be called.  So that is definitely something I have learned about all this.

Tuesday, 14 August 2012

Obligatory ColdFusion Roadmap article

G'day
Like the vapid echo-chamber that it is, Twitter had been resounding with content-nil repetition of people restating what Adobe announced overnight: a public-facing roadmap for the direction of ColdFusion and ColdFusion Builder.

I struggle to communicate anything of merit in 140 characters (so... much the same as anyone else then  ;-), so I'll write about it here instead.

First up: heres a link to the official blog post, linked from which is the roadmap PDF.


Monday, 13 August 2012

Communications policy

G'day
Just a quick note.

Please do email me about anything you read on the blog... the email address to use is cameron.adam+blog AT gmail.com (I dunno if I need to do that anti-spam thing?).

Bear in mind that I reserve the right to reproduce in part or in whole any emails you send me.  If I quote just a part of it, I will make sure not to alter the context of what you have said.

Unless you state otherwise, I will also cite your name (but, obviously, not your contact details!).  If you specifically ask not to be identified, I will respect that.

All in all though, please consider commenting on the blog rather than emailing direct, if whatever you want to say relates to something I've said on the blog.

Update:
I'm fed-up with inane "my favourite platform is better than your favourite platform" comments being posted against articles that have nothing to do with the comparison of various CFML platforms. In fact even when the article is actually about such comparisons, such comments are completely insightless, so just not worth making.  If you post stuff like that, you're a f*ckwit.  And I will delete the comment. So don't bother.

Cheers.

--
Adam

Olympic tables

G'day
Right, so that's the main Olympics over and done with, so I'll get rid of the medal tables from the right-hand-side of the blog page, and will just post them here for posterity.

Below are all the countries my readership comes from (with the top three placings for the given metric as well), with their total Olympic medal tally, adjusted for population: