Monday, 31 December 2012

Lists with empty-string delimiters

G'day:
Blimey; three articles today. Once again, this stems from a thread on the Railo Google Group, this time regarding a bug I found in Railo (or that I think is a bug), which resulted in some questioning whether it's a bug in Railo, a bug in ColdFusion, or a bug in both. And the more I look into it, the less sure I am about it.

And the situation I found the... erm... "anomalous  behaviour" (shall I say) was in the code I was writing for the previous two articles' investigation.

Don't optimise your code (annexe)

G'day (again):
In the previous article I alluded to the fact I had more to say on the approach I had to creating my test strings for those experiments. This'll just be short, as it's a variation on the same theme, and I just thought I'd share this with you.

For the previous tests I saved a million-char randomly generated string to test on. Whilst writing the code for this, I noticed some significant performance differences in various different techniques I was using to build the string.  And these are perhaps worth remembering, as far as potential optimisations go.

Don't optimise your code

G'day:
Well that headline is a gross over-simplification of what I'm going to say here. Obviously one should write code that's optimal for the task at hand, but there's a time and place for doing this sort of thing.

The Railo Google Group seems to be my muse this week (which is a sorry indictment of me on a coupla levels), after yesterday's [ed: it was y/day when I started this, it was a few days ago now] inspiration regarding making CFML built-in functions "first-class", and now this article about premature optimisation.

Friday, 28 December 2012

Callbacks and built-in functions as first-class functions

G'day:
This will be my most unplanned blog article to date. I saw a thread on the Railo newsgroup over Xmas, and whilst catching up with my responses just now, decided "oh, I'll be able to come up with an article about that".

The posting on the mailing list was asking whether one can pass a built-in function (BIF) as a callback.

I currently have no idea what I'm about to say about this, so I am as interested in what I continue to type as you are (the conceit is that if you've got this far, you have at least a small amount of interest)...

Thursday, 27 December 2012

More balance, fewer @rseholes

G'day:
There's been a bit of back-and-forth on Twitter (nothing of any merit, sadly) regarding my posting from the other day regarding some "shortcomings" in the attitude of some of the users on Stack Overflow, and also - given how said users behave - some potential areas for improvement in the Stack Overflow process.

I don't contest that the first part of the article was quite vitriol-laden, and that was by design. However later in the article I did try to discuss - in an objective, balanced way (? well, mostly) - where I think things could be improved.  However I think I did not succeed in the objectivity, or some people didn't get past the headline, or if they got that far, didn't read past the vitriol. I am guilty of doing this (to myself) in my writing sometimes.

Anyway, the article was put on the twitter radar of one of the blokes who started Stack Overflow (thanks Stephen Moretti for thinking to do that), and there was a brief exchange between myself and Jeff Atwood (the S/O bloke) and some others. I think Jeff was a bit defensive, but in his defence, I can see how he'd find my article incendiary. And equally my responses to him could have been more diplomatic. Well the ones I made just now, anyhow. I'll leave it to you - the reader - to dig it up in my Twitter history if you so choose. It's not very exciting.

So, here I am again. What I'm going to try to do in this article is to articulate my point differently:
  • no vitriol, snippiness, back-handedness or passive aggressiveness (this will be a stretch for me, as you can imagine ;-)
  • maintaining objectivity (OK, that's a variation on the above);
  • trying to convey my thoughts more clearly than I have previously.

The very first thing I'd like to say is I really like Stack Overflow! Jeff, if you only glance at this article before dismissing it, hopfully you'll see that bold red bit there.

Wednesday, 26 December 2012

Regular expressions in CFML (part 5: syntax - look-arounds, and how the engine parses the string it's matching)

G'day:
This is part five of the series I started with the introduction article: "Regular Expressions in ColdFusion (part 1: overview)", and followed with a discussion entitled "Regular expressions in ColdFusion (part 2: concepts)". Then I moved onto syntax with "Regular expressions in ColdFusion (part 3: syntax - single characters)" and "Regular expressions in ColdFusion (part 4: syntax - repetition, sub-expressions and back-references)".

Please note that this article - more so than the other ones - does not stand-alone. It's more a "part 2" of the preceding article. I advise reading at least that one before reading this one. But, really, one should read the whole lot in order. But bring food and water with you before starting.

Look-arounds

Another type of sub-expression is a look-around. Look-arounds do what the name suggests: they look around to see if there's a match (or there specifically isn't a match). They can look ahead from the current position in the string being processed, or they can look behind. So we have four different sorts of look-around:
  • positive look-ahead;
  • negative look-ahead;
  • positive look-behind;
  • negative look-behind.
ColdFusion's regex engine only supports look-aheads (both positive and negative ones).

Before I explain how these work, let's back up a bit and examine what goes on when a regular expression pattern matching exercise takes place on a given string.

Tuesday, 25 December 2012

Christmas Spirit, StackOverflow style (#2 in a list of why StackOverflow is populated by @rseholes)

G'day:
Is it the season for "Peace on Earth and goodwill to all men"? No, on StackOverflow it's more like "Screw you, newbie @rsehole: I have power over you, die die die" for some people. And, again, people like this demonstrate how the Stackoverflow approach to site self-management needs some thought.

NB:
If you read this article, also please make sure you read the follow-up to it as well.


A newbie ColdFusion user has posted a newbie-ish question over on Stackoverflow. Given the treatment they've received from non-ColdFusion users over there, I would not be surprised if it's their last.  Here's a summary of their question (by someone called "volume one"):

Monday, 24 December 2012

Regular expressions in CFML (part 4: syntax - repetition, sub-expressions and back-references)

G'day:
This is part four of the series I started with the introduction article: "Regular Expressions in ColdFusion (part 1: overview)", and followed with a discussion entitled "Regular expressions in ColdFusion (part 2: concepts)". Then I moved onto syntax with "Regular expressions in ColdFusion (part 3: syntax - single characters)".

Repetition (again)

In a previous article I listed the types of repetition one can express in a regex:
  • Zero times
  • Zero or one times
  • Zero our more times
  • One time
  • One our more times
  • An exact number of times
  • Between a specified minimum and maximum number of times
  • At least a minimum number of times

Saturday, 22 December 2012

Regular expressions in CFML (part 3: syntax - single characters)

G'day:
This is part three of the series I started with the introduction article: "Regular Expressions in ColdFusion (part 1: overview)", and followed with a discussion entitled "Regular expressions in ColdFusion (part 2: concepts)".

Syntax

OK, so I'm now going to try to describe how all those concepts are actually reflected in regex syntax. This is where I am going to dispense with most of the keys on the keyboard, and just use the punctuation keys ;-)

(not really)

I'll go through each of those concepts in turn.

Friday, 21 December 2012

Need help? Know how to ask for it

G'day:
This article is borne out of exasperation rising from feeling with people on StackOverflow. But this time not the nazi muppets who like to think they are in a position of authority (and they're at it again today...), but the people asking the questions. To be fair: not all the people asking the questions, but a reasonable percentage of them. An uncomfortably high percentage of them. And the same extends to people asking questions on the Adobe ColdFusion forums, and other similar environments created for people to seek and get help.

I never cease to be amazed at how bloody useless people are at asking for help. And continue to marvel (not in a good way) at how disconnected from reality people must be to approach asking for help the way they go about it. And even before getting to the point of asking for help, how lacking in gumption people can be when it comes to trying to solve their own problems before expecting someone else to pitch-in and help them.

Before I start ranting too much (some might say "too late!" but I've only just started, trust me)... I enjoy participating on help forums. I've been doing it since I first located the alt.comp.lang.coldfusion Usenet group in 2001 (I started with CF in late 1999).  I enjoy the feeling I get when I've successfully helped someone move past a problem (both for myself, and knowing that the other bod will be pleased to move on from this stumbling block they'd encountered); I like the selfish sense of satisfaction I get when I work something out that someone else couldn't work out (I'm not proud of this, but I'm a realist, and it is a factor); most of all I like it when I initially don't know the answer to something I'm trying to help with, and end up learning something as a result. It also helps the ColdFusion community keep ticking over, which Adobe kinda leave up to us to do, so that's gotta be good for ColdFusion's viability going forward. Albeit in a very small way. But community activity is important to the viability of the language, I think.

Anyway, as much as I enjoy it, boy do I find it irritating at times. You probably got that already.

OK, so what's the problem?  Actually the problem is basically described by inference in this distillation of how to ask questions the smart way. It should be required reading for anyone signing up to a help forum. It should be required reading for everyone working in technology. Go read it. Now. But here's my take on where people go wrong when they encounter a problem they don't know the answer to, and where they start going wrong right from the outset.


Identify the problem

If you encounter a problem - like getting CF error on your screen - approach solving it coherently. A lot of people when they get bamboozled by an error simply start trying random things to try to solve it: "I'll restart CF and see if that helps". "I'll use a list instead of an array". "I'll just rewrite it, maybe it'll go away". This is a daft approach to solving things. Even if the problem does happen to go away, you probably won't end up knowing what the problem was, so you really can't be sure it's not some sort of transient problem that didn't just not occur after your remedial action because of some contributing factor that was not present at the time you tested. Plus isn't it nice to know what caused a problem so you don't do it again, rather than just masking it?  Also generally random actions like this don't help, and just make things worse, so attacking things incoherently is just a waste of time in a situation in which you're already probably not wanting to "invest" your time. This just increases frustration.

I use scientific method when I'm faced with a problem I can't nut out. Well a layperson's version of it anyhow. The process I use is basically this:
  1. Make an observation, eg: the manifestation of the error on the screen, or the unexpected results, or whatever it is.
  2. Form a hypothesis of what could be causing the error ("ah... that application-scoped variable has vanished").
  3. Identify the manifestations / side-effects of the situation being hypothesised ("well if that variable has been blitzed, I'll be able to tell by looking in this other place").
  4. Formulate an experiment to test the hypothesis, giving consideration to the bits identified in (3), as well as making sure the results of the experiment will conclusively demonstrate that the hypothesis is borne out. EG: simply restarting CF is not going to be a good experiment for testing a missing application scoped variable, as it doesn't actually identify what caused the problem in the first place. Basically you need measurable results (not just a nebulous change in state).
  5. Perform the experiment, and aggregate the results & any side-effects noticed from the experiment, which might need to be tuned-out in subsequent round of experiment.
  6. Draw a conclusion based on the results. Do the results of the experiment bear out the hypothesis? Quite possibly not, but they should help to finetune the next test of the hypothesis, or alter the hypothesis itself.
  7. Rinse and repeat as necessary.
Now I'm not suggesting one needs to don a labcoat and deploy the pocket protectors to do all this (but hey, if that's your outfit already, all good ;-).  All it means is stop and give some thought to what you're doing, work out a coherent way to test the situation and approach things logically.

Most people I know don't do this, they just throw their hands up in despair (or in a jazz-esque sort of way) and post all their code to StackOverflow going "doesn't work".

And most people really struggle with step 4 there. Judging by the code people end up posting on the the forums, they don't generally have a concept of a portable reproduction case. If - for example - you are having an issue with a JDBC error coming back from a <cfquery> tag, the only things that are relevant are:
  • the SQL statement being passed to the DB driver;
  • any variables that contribute to the construction of said string;
  • the values of any parameters being passed;
  • the data source (and, by inference, which DB server one is using, eg: Oracle, MySQL etc);
  • depending on the nature of the error, the schemas of any tables etc being queried;
  • the error message
  • what the expected results were ("this query is supposed to return [whatever]" or similar)
What is not relevant to any of this is:
  • any code after the <cfquery> tag
  • any code before the <cfquery> tag that don't contribute to the points above;
  • never ever ever any "code" other than CFML. HTML is never going to be relevant to a CF error.
But what I often see posted to forums (or maybe in pastebin etc if the person is remotely sensible in that regard) is the contents of the entire file the error occurs in, including all mark-up, CSS, JS, and unrelated CFML. The immediate effect this has on me is to think:
  • they've done bugger-all of their own troubleshooting if they haven't actually factored-out any of that from contributing to the situation;
  • it's not occurred to them that by posting all that cruft, the person reading the issue is kinda forced to wade through it if only to find the bit they're talking about;
  • if they can't be arsed doing any troubleshooting, why would they think I should be arsed either?

Now... back to my mention of a repro case. What one should do in this situation is pull the code that's causing the problem completely out of the context it's running in, mock the variables that it uses as inputs to perform its logic, decide what one would expect to get as a result, and then run the code. There will be three possible results of this:

  1. If the code works, then one's assumptions as to what the problem is are actually incorrect.  It suggests that one of the inputs is not what one thought it is. That needs to be tracked down and then shift the repro case to that code to work out what the story is. This is forward progress because it has fine-tuned one's understanding of the issue.
  2. If the code doesn't work in a different way from the initial error then one hasn't replicated the inputs properly. This needs to be fixed, and then the experiment repeated. In doing this, it will clarify what's going on and what's contributing to the problem. By the very nature that one's initial baseline expectation of the inputs and the results were off suggests that there's something missing from the analysis of the situation. This is a forward step in solving the problem.
  3. If the code errors in exactly the same way as it was in its original context, then one has a repro case, and one has greatly reduced the factors that could be contributing to it. From here, it's generally pretty easy to work out what's wrong. Almost all issues that initially seemed "weird", "like a bug in ColdFusion", or "just don't make any sense" get solved at this point.
If one is still at stages 1-2, then one is not yet ready to post to a forum for help. Once one gets to stage 3 - and still hasn't cracked the problem - one's got a nice terse piece of code with known inputs and outputs which can be posted to a forum. At this point one will have a far better understanding of what's going on, can articulate the experimentation that has already been done and discarded as not contributing, and there's a small piece of code that someone trying to help can copy & paste down to their local system and run without having to horse around too much. It's also demonstrated that a reasonable amount of effort has already gone into trying to sort it out one's self, which will be a positive sign to anyone thinking of helping. Plus a lot of potential help suggestions will have already been tested and discarded, saving the people helping some time. It's an all-round win.

Also, if perchance the repro case demonstrates a ColdFusion bug, you've already got a repro case to send to Adobe. Excellent.

Describe the problem

A lot of this will have been covered already if the approach above has been taken. But what I mean here is too many people start a thread / question and basically say something along the lines of "I've got this code and it doesn't work. Why doesn't it work?"  The issue here is the person reading it doesn't know what constitutes "not working". It could mean there's an error. But one still doesn't know what sort of error (compile error, logic error, SQL error, etc); it could mean one was expecting ten rows back from the DB and is only getting one; it could mean the table is outputting ten rows by five columns when one wanted five rows of ten columns. The point is: one needs to identify what constitutes "not working". Seriously, this should be bloody obvious, but for some reason it is not.

Furthermore, if one has got an error, one needs to post the bloody error message. Do not describe the error (yes, people do this: "oh I got some error about the array being wrong").  And if there's code involved (OK, obviously with an error code will be involved! ;-), post the code and identify which line the error is saying is a problem.

Pay attention

Actually.... let's back up. Before posting the error... read the bloody thing. So many questions I see are asking what the problem is where the error message is saying exactly what the problem is, and is identifying the precise line and column of the line the problem is at (usually this is with compile errors). Even if they're not that explicit, ColdFusion errors are generally very descriptive, and do pretty much identify what's gone wrong. I also encounter people who say "oh, I never understand that stuff" (seriously!), but when challenged and I say "OK, which word are you struggling with?" and ask "OK, even if you've not heard the term before: what do you think a 'complex object' [for example] might be?" they realise that it's just a case of never having bothered paying attention to the error message, rather than it being impenetrable in some way. I would say 80% of errors I get asked about can be solved by simply reading the error message.

There is no such thing as telepathy

People also have a tendency to assume that just because they know something (or are aware of something about their environment) that everyone else magically will. This is not the case. No-one else is privy to the internal mechinations of your mind, nor with they know your enviroment (or even your ColdFusion version, etc). One needs to make sure that any environment consideration or other peripheral factor needs to be actually articulated. People might be able to guess, but people probably actually can't. But either way: they shouldn't be made to guess. If nothing else it's a barrier to them helping you, which is counterproductive for you.  Consider this problem (this is actually something that I have had to deal with in the past):

SELECT        *
FROM        someTable
WHERE        someColumn = #someValue#
ORDER BY    anotherColumn
LIMIT        5

My DSN is MySQL, but this errors for some reason. If I run the same query in MySQL it works fine.
The problem isn't the filter or the table schema or anything like that. It's that this code wasn't a DB query, it was a QoQ on an earlier-fetched record set. The initial data came from MySQL, sure... but it didn't occur to the person that a QoQ is not run on the DB server, it's run on CF's own little SQL stub thing, and that doesn't support LIMIT.

Now the person should have just read the damned error message (and posted it), but at the very least they should have mentioned that this wasn't a DB query.

There is no such thing as telepathy (redux)

Another thing you need to do is to research the issue, once you've identified it. This means googling error messages, programming constructs you're struggling with, and anything else relevant. And if one still needs to ask for help (TBH, googling will solve 80% of problems: very few problems are unique), then part of your question should also detail what sort of research you've already done. Because if you don't mention it, then the first valid sugggestion one ought to offer you is "did you google it?". Some of you might think "well of course I will have researched it first, that goes without saying", but let me assure you: you're the good 'uns. Most people are bloody useless, and all they do is use StackOverflow and other forums as a kind of mechanical turk: to try to get other people to be their search engines. So let us know what you've already found. Also let us know what things you've found which might seem like a solution, but turned out not to be: this will save us making the same suggestion to you, and it's also useful information to fine-tune your issue.

Most errors are your fault

A lot of people posting questions start off from a fairly defensive position that whatever is going wrong, it's not their fault. They'll say "I don't know what's wrong, because my code works fine", or "I've found a bug in ColdFusion".  I'm sorry, but almost always this is not the case. 99% of the time... perhaps more... it's a problem with the code or the approach, or something like that. ColdFusion might have a number of bugs, but they're generally pretty esoteric these days, so the odds of someone who is having a problem with a listAppend() statement having suddenly found a new bug in listAppend() is rather small.

The problem I have with this way of thinking is that it's much easier to discover what a problem is if one starts with the mindset that it's one's self who's cocked-up, rather than someone else or Adobe. Firstly because it almost certainly is them, but secondly because is one is troubleshooting in a defensive way and going "well I know that works, so it can't be that", one's not going to spot the fact that actually it is that code that's got the problem. I think it's also a logical fallacy that "well my code works, so it can't be that, it must be something else", because the evidence that has lead one to decide something is wrong will be manifesting from a line in one's own code, so - really - even on first indications that's probably where the problem lies.

Approach this stuff with... um... an open mind (or just a neutral mind... just not a closed mind), and one will be in the best place mentally to find the problem.

Also one comes across as a bit of a cock if one starts asserting it's a bug in CF but it happens to be that they don't know the difference between listFind() and listContains() (or just didn't spot they'd used the wrong one). And it's best to not look like a cock if possible, yes? ;-)


Well that was a nice rant for a Friday just before Xmas, wasn't it?

I'm off to Ireland from tomorrow through until Dec 27 - I get to see my son for a dozen or so hours in that time... thankfully 2h of which is on Xmas Day - so I dunno how much attention this blog will get across that period. On one hand I'll have my laptop with me, but on the other hand finding internet connectivity is tricky. But I'm mostly stuck out in the middle of nowhere with little else to do, so perhaps wittering on will pass the time. Who knows?  I'll at least get part 3 of the regex stuff posted at some stage in the next coupla days.

In case this is it before you head off to do festive things that are more interesting than hanging on my every blog-written word, have a good break. And make sure to eat too much. And have a beer for me.

Merry Xmas.

--
Adam

Thursday, 20 December 2012

Positive Communication from Adobe regarding ColdFusion: more thoughts

G'day (again):
I'm following the comment thread on the "ColdFusion: News, Initiatives and Updates from Adobe" blog post on the Adobe blog that got posted a few days ago. I offered my first tranche of feedback a coupla days ago, and here's my second lot.

These are replies to people's comments, and some general thoughts. I'm posting them here rather than there because this is too long for a comment cluttering-up someone else's blog. I'll cross reference this article over there too though. Also I want to get this discussion on the radar of my readers too, in case they're not aware of it, or have not thought/bothered to follow it.

I've worked my way down the comments, and commented / responded as I go. It's a bit stream-of-consciousness.

Regular expressions in CFML (part 2: concepts)

G'day:
This is part two of the series I started with the introduction article: "Regular Expressions in ColdFusion (part 1: overview)". Initially I set out to only write one article, but by the time it was over 8000 words long, I figured I should split it up and serialise it otherwise no-one would be brave enough to read the whole thing.  If you see references in the text to "see above" or "see below", it might refer to something in one of the other articles. I'll try to find them all and replace with links, but no-doubt I'll miss some.

Concepts / components of a regular expression

A regular expression is built out of all those seemingly random sequences of punctuation characters. Taken en masse, that's quite impenetrable, and it's good to take a step back to consider the various notions / components / building blocks that are important to regexes. This is just a narrative / conceptual discussion, rather than delving into syntax, just for the moment. Knowing about the concepts is more important as the minutiae of the syntax, and once we have a handle on the concepts, the synactical vagaries will make more sense, and the expressions themselves will seem less daunting. In theory ;-)

Wednesday, 19 December 2012

When functions do too much, and how to get them to do more

G'day:
After soliciting more UDFs for CFLib a while ago, I've been dead slack at processing the inbound queue, and fixing some bugs people have found. Sorry about that. I started playing catch-up at lunchtime today: you might have noticed a coupla bugfixes bubbling through on Twitter if you follow the @cfbloggers feed.

Tuesday, 18 December 2012

Regular expressions in CFML (part 1: overview)

G'day:

Before I start
This started off being a single article, but it ended up way too long. And by the time I've come to be divvying it up, I'm thoroughly fed-up with it, so I'm not going to do the usual book-ending of each "sub-article", I'm just gonna fairly arbitrarily cut the thing into sections, and post each section as a new article. So it's gonna be best to start at the beginning and work through to the end, as the subsequent articles might not be fully contextualised in and of themselves. I'm also gonna serialise the thing over a few days, rather than releasing them all at once. Anyway... hold on to yer hat... regular expressions...

I've been mulling-over writing this article since I first started this blog. On one hand I'm fairly good with regular expressions, and a lot of ColdFusion developers (most of the ones I have encountered, anyhow) are not. So there's potential for a teaching exercise there. On the other hand Ben Nadel had banged-on so much about regexes so much in the past one might think there's little else left say on the matter.

Positive Communication from Adobe regarding ColdFusion

G'day:
In a break from the perceived doom & gloom I have been seeing recently regarding CFML - this blog, Sean's blog, Andy's blog (Andy's gripe is specifically about the ColdFusion installers not working on the current versions of Windows), the Fusion Authority blog etc, some  stuff from the Railo community (which seems a bit counterproductive to their cause, but it's only an element of the lunatic fringe that engage in this), and various series' of sound-bites on Twitter - Adobe published a very positive-sounding article on their official ColdFusion blog yesterday. It should come as no surprise that Adobe are sounding positive about their product, but it's really not something we hear too much of too often (Rakshith, take note ;-).

One might think that the article was all just self-promotion & marketing spiel, but this one actually had a bit of meat to it, which was refreshing.

Friday, 14 December 2012

Am I right to think this is stupid?

G'day:
This was brought to my attention via a thread on the Adobe forums in which someone was messing around with "closure" functions being used as callbacks.  One of the statements they made was:

The only thing I observed: a closure does not seem to be a function, because isCustomFuntion (..) returns false. Maybe this should be changed, I dunno.
My reaction to that was "[cough]bullshit", but I decided I better not back my instinct, I'd better make sure I was right first.  But I wasn't right. Typically, the online docs for isCustomFunction() are not much help here:

The IsCustomFunction function returns True for any function that can be called as a custom function, including functions defined using CFScript function declarations and cffunction tags, and functions that are ColdFusion component methods. For CFC methods, first instantiate the component.
On first take - other than having moderately curious wording -  that seems to suggest what is logical: if I create a function with function / cffunction etc, and pass it to isCustomFunction(), I'll get a TRUE result. If what I pass it is anything else (eg: just a string, or a struct or something), I'll get a FALSE.  However this is not the case.

Tuesday, 11 December 2012

Wanting script to work like tags (#1 in a series of "fool's errands")

G'day:
Ever since ColdFusion 9 implemented a jerry-built1 way of making DB calls in CFScript via Query.cfc, people have been observing/complaining/hand-wringing that the way one passes the SQL string from the calling code to JDBC via CFML is much more elegant with the CFQUERY tag than it is with using Query.cfc. In case  the situation if not clear, here's an example:


Thursday, 6 December 2012

Constants for CFML

G'day:
This one is just an idea I had for ColdFusion 11 (or Railo... just "for CFML" really). Well it's not an idea that's particular to me, nor is it a new one. Or an earth-shattering one. Or one that will sell any licences in and of itself. It would be handy though.

CFML has no notion of named constants, EG:

const PI = 3; // near enough ;-)

Whilst one can created variables, not all values are supposed to be variable. For example π doesn't change: it's not a variable. It doesn't vary.

Wednesday, 5 December 2012

Forgot to say

G'day:
OK, I often say "this'll be a quick one", and then waffle on for a coupla thousand words. Not this time: it'll be quick.

One thing I forgot to mention in the "I love being wrong" article I posted a few hours ago was how I determined that the form scope was indeed being deleted and reconstructed every request, not simply being cleared (because as I mentioned: it's being both cleared and deleted, which seems logically tautological, if you see what I mean).

I love being wrong

G'day:
That's not sarcasm, I actually do rather like being wrong about stuff: it's a great vector for learning new things and improving one's knowledge. Provided one doesn't get defensive about being wrong (which if just daft), and does endeavour to understand how one was wrong, and do something about it.

Anyway, enough airy-fairy philosophising. What was I wrong about?

The form scope.

Monday, 3 December 2012

Survey Results: where to focus Adobe's efforts to improve CFML's CFScript coverage

G'day:
Thanks to a coupla people fwding my Twitter status updates asking for participation, and I guess repeated nagging from myself; on Friday last week I finally hit my target of 50 responses.  I've closed that survey now.

The results were fairly predictable, I guess: no-one's interested in UI-ish things (form, layout & UI widgets) being availed in CFScript, and a bit of a mix in between.  Basically people thought "internal" type stuff, or integration with some external systems warranted inclusion in CFScript, but were a bit "meh" about it other than that.

Sunday, 2 December 2012

What's up with OpenBD?

G'day
This is just a quick one.

I found myself - yet again - typing into one of my articles (an update to yesterday's one which discussed CFML's date datatypes) something to this effect "but the code didn't work on OpenBD, so I didn't bother testing it".

Saturday, 1 December 2012

What you see is not necessarily what you get

G'day
This is another case of me not having enough space on Stack Overflow to articulate myself properly, so I'm creating a blog article and will cross reference my answer to here. With enough of a summary on S/O to try to avoid snippy comments from the self-appointed sheriffs.

Friday, 30 November 2012

Stack Overflow is populated by @rseholes (#1 of what could end up being a series...)

G'day

RANT ALERT! (and language some people will find unpleasant).
Since I started this blog, I've had a link over on the right-hand side of the page encouraging people to help out other ColdFusion developers on the ColdFusion channel on Stack Overflow (and on the Adobe ColdFusion forums). I stand by my sentiment that it's important to help people, but I've about had a gutsful of Stack Overflow. Not the concept - it's admirable - but the "gimme-a-little-power-and-I-become-a-nazi" fvckwits who try to find meaning in their pathetic little lives by demonstrating how they have a tiny tiny tiny amount of authority over other people, and by god, they will exercise it.

Thursday, 29 November 2012

Wednesday, 28 November 2012

ColdFusion 10 hosting, anyone?

G'day:
In the course of doing this blog and writing example code for it, or knocking together small applications to help myself and possibly other people, I need a small amount of code to be hosted in a public-facing environment.  Examples of this are the ColdFusion (and ColdFusion Builder) Bugs RSS feeds, my experimental easier-to-use search UI for the Adobe bug tracker, and the Twitter bug notifier thingey. These all run fine on CF9, but there's a few things I want to try which require CF10 (mostly stuff I want to experiment with, like web sockets).

Saturday, 24 November 2012

Thoughts on "Coldfusion and the law of dialectics of progress" by Stofke on wheels

G'day:
This is another article that started as a comment on someone else's blog, but it got too long, so I figured I'd clutter up my own blog rather than theirs.

"Stofke on wheels" has written an interesting article entitled "Coldfusion and the law of dialectics of progress" (I wish I could come up with titles like that... without simply just copying it, like I have in this article, I mean ;-)
 
The article starts well - discussing a concept I was unaware of "Law of the handicap of a head start" - and how it possibly applies to ColdFusion - but ultimately arrives at some dubious conclusions as to how Railo is an answer to the questions left asking.

Wednesday, 21 November 2012

CFLib.org needs your UDFs

G'day:
 I assume you all now what CFlib.org is, but in case not, it summarises itself thus:
The purpose of the Common Function Library Project (CFLib.org) is to create a set of user-defined function (UDF) libraries for ColdFusion 5.0 and higher. These libraries are open source and may be used and modified to your liking. Functions range from email format checking to encryption routines. These UDFs can greatly speed up development time as well as add new and powerful features to your web site.

Anyone can add their code to the project by simply using our submission form. You must be running ColdFusion 5.0 (or higher) to run these libraries. For more information about ColdFusion, please visit Adobe's ColdFusion product page. If you have any suggestions or comments, please contact me. CFLib.org was created by Raymond Camden [...].

Tuesday, 20 November 2012

Monday, 19 November 2012

ColdFusion 10 Update 5: mostly smooth

G'day:
Here's my experience with the new ColdFusion 10 update 5 which was released half an hour or so ago.

Sean said that Nick said that Fusion Authority said...

G'day
Sean Corfield's written an interesting article entitled "CFML - Too Little, Too late?". I recommend you read it. It's not earthshattering and not saying anything that hasn't been said before, but it's nicely composed and is poignant and thought-provoking. And I tend to pay attention when Sean says stuff. I don't necessarily then agree, but I do pay attention ;-)

I started feeding-back to him in a comment on his own blog, but it was getting too long for a blog comment so I thought I'd revise it slightly to add context, and write it here instead.

Friday, 16 November 2012

Slashes are not more important than people


First things first

CFHour is asking people to donate money for the relief of victims of Hurricane Sandy.

To encourage people to donate, they are running a competition to win a copy of ColdFusion Builder.  Details are on their site, but I've repeated them below to get the message across as quickly as possible (guys, please let me know if I don't have this exactly right, I'll update it).

Donate some money to a charity that is targeting the relief of victims of Hurricane Sandy. Take a photo of the receipt and post it somewhere on the 'net that can be viewed (obscure any sensitive personal info!), then tweet the URL along with a hash-tag of #CFHourCares.


"Too-hard basket"

G'day:

Update:
This survey is now complete. The results can be found here.

Yesterday I nudged my readers about the survey I'm doing about CFScript improvements in CF11.  I had some feedback overnight from Charlie (in the comments below) and another person saying much the same thing: the survey is a bit hard to fill out.  Indeed the anonymous comment in the survey answers was precisely:

God that was hard to complete. You should have grouped tags from the same family into one. e.g. all the cfform tags as 1 option.

Thursday, 15 November 2012

Custom tags: nesting

G'day:
I meant to write this one ages and ages ago, back when I did the previous article on looping with custom tags. As I said in that one, I think custom tags are a great concept, but have been a bit eclipsed by all the non-UI-centric things that have been added to ColdFusion in recent years, and they've fallen out of fashion a bit. I think they still have a place in CFML's arsenal, and do things in a way that is more elegant that other more recent alternatives, when used appropriately.

Nudge: CFScript enhancements in ColdFusion 11 survey

G'day:
This is just a brief nudge. A coupla weeks back I wrote an article asking where any focus on improving CFScript's coverage of CFML tags should be applied for ColdFusion 11, and this contained a survey to gauge what people thought were important omissions, or what they thought was unecessary in CFScript.
Update:
This survey is now complete. The results can be found here.

Tuesday, 13 November 2012

Plug: Learn ColdFusion in a Week

G'day:
Every man and his dog have mentioned the new resource that was launched within the last week: learncfinaweek.com. Except me.  Well I'm remedying that now.

Do we know if ColdFusion 10 update 4 actually does fix these performance/scaling problems?

G'day
I'm still too busy with other stuff to write an article with any meat on it, I'm afraid.  Although that one about rationalising the useage of trailing slashes kept at least me amused for a coupla days. But I'm easily amused.

But here's a formalisation of a thought that's been lodged in my brain for a week or so now.

Thursday, 8 November 2012

/>

G'day:
It's been a quiet week on the blog front this week sorry... this is down to it being a pretty busy week in general for me.  Nothing exciting... just too much work, so little motivation to spend even more time in front of the screen when I get home.  And, to be frank, I've not been in the mood to write anything on the train in the morning either. This isn't for a lack of stuff to write, it's just what I've got in the list of things to write about takes research and... well... a bunch of actual work to get the thing ready.

So this is a bit of a filler article.

Saturday, 3 November 2012

CFML: Application.cfc-set mappings don't work in onApplicationEnd

G'day:
Well this was not what I was intending to be looking at this evening, but I made the mistake of  looking at StackOverflow and didn't understand what I was reading about mappings and onSessionEnd and ColdFusion 8, so looked into it.


I don't really care about quirks of CF8: the boat's pretty much sailed on any problems anyone finds with that.  However I wanted to make sure it wasn't still happening in CF9 or CF10.

The original problem is that ColdFusion mappings that are set in Application.cfc don't seem to exist by the time onSessionEnd() runs (this is on ColdFusion 8).  Here's some test code and the results:

<cfcomponent output="true">
    
    <cfset this.name = "testMappings">
    <cfset this.sessionManagement = true>
    <cfset this.applicationTimeout    = createTimespan(0,0,0,20)>
    <cfset this.sessionTimeout        = createTimespan(0,0,0,10)>
    
    <cfset this.mappings = structNew()>
    <cfset this.mappings["/test"] = "C:\temp">
    
    <cfset testExpandPath("Pseudoconstructor")>
    
    <cffunction name="onApplicationStart" returnType="boolean" output="true">
        <cfset testExpandPath("onApplicationStart")>
        <cfreturn true>
    </cffunction>

    <cffunction name="onApplicationEnd" returnType="void" output="true">
        <cfargument name="applicationScope" required="true">
        <cfset testExpandPath("onApplicationEnd")>
    </cffunction>
    
    <cffunction name="onRequestStart" returnType="boolean" output="true">
        <cfargument name="thePage" type="string" required="true">
        <cfset testExpandPath("onRequestStart")>
        <cfreturn true>
    </cffunction>

    <cffunction name="onRequest" returnType="void">
        <cfargument name="thePage" type="string" required="true">
        <cfset testExpandPath("onRequest")>
        <cfinclude template="#arguments.thePage#">
    </cffunction>

    <cffunction name="onRequestEnd" returnType="void" output="true">
        <cfargument name="thePage" type="string" required="true">
        <cfset testExpandPath("onRequestEnd")>
    </cffunction>

    <cffunction name="onSessionStart" returnType="void" output="true">
        <cfset testExpandPath("onSessionStart")>
    </cffunction>

    <cffunction name="onSessionEnd" returnType="void" output="true">
        <cfargument name="sessionScope" type="struct" required="true">
        <cfargument name="appScope" type="struct" required="false">
        <cfset testExpandPath("onSessionEnd")>
    </cffunction>


    <cffunction name="testExpandPath" returntype="void" access="public" output="true">
        <cfargument name="message" required="true" type="string">

        <cfset var path  = expandPath("/test")>
        <cfset var fullMessage = "#message#: #path#">
        <cfoutput>#fullMessage#<br /></cfoutput>
        <cflog file="testMappings" text="#fullMessage#">
    </cffunction>

</cfcomponent>

Pseudoconstructor: C:\apps\adobe\ColdFusion\8\instances\CF801\cfusion.ear\cfusion.war\test
onApplicationStart: C:\temp
onSessionStart: C:\temp
onRequestStart: C:\temp
onRequest: C:\temp
test.cfm: C:\temp
onRequestEnd: C:\temp
onSessionEnd: C:\apps\adobe\ColdFusion\8\instances\CF801\cfusion.ear\cfusion.war\test
onApplicationEnd: C:\apps\adobe\ColdFusion\8\instances\CF801\cfusion.ear\cfusion.war\test

Firstly, it's completely legit that the mapping doesn't work in the pseudoconstructor.  See my article on how the settings set in the this scope work if you're not sure why.

However to me it's a bug that they aren't still around in onSessionEnd() and onApplicationEnd().  Someone at Adobe clearly thinks so too, as the behaviour has been modified (partially) in CF9:

Pseudoconstructor: C:\webroots\CF902\test
onApplicationStart: C:\temp
onSessionStart: C:\temp
onRequestStart: C:\temp
onRequest: C:\temp
test.cfm: C:\temp
onRequestEnd: C:\temp
onSessionEnd: C:\temp
onApplicationEnd: C:\webroots\CF902\test

onSessionEnd() has been fixed, but not onApplicationEnd().  You'd think that if someone took the time to fix one of these, they might check the other one too eh?  Apparently not.

It's the same behaviour in ColdFusion 10.  But Railo (4.0.013) works fine: the mapping is still available in onApplicationEnd().

I've raised a bug for this: 3358817.

The work around - such as it is - for this is to set the mappings in CFAdmin: then they work fine.  Not much of a work around, but it might help some people.

Righto.

--
Adam

103*

G'day:
(People in USA will probably not get the cricket score reference in the title of this one).

I just noticed I made it past 100 articles.  When I first started this, I had plans for about half a dozen articles, and was worried what I was gonna blather on about after that. I also thought my attention would wander fairly quickly and I'd get bored of writing stuff up.  It seems not so far.

I've still only got plans for about a dozen articles ahead of where I am now, but fortunately Adobe, Railo, and the CFML community manage to keep me intrigued / bemused enough to inspire me to have more stuff to write about every other day (or so).

Cool.

Anyway, cheers for sticking with me.

--
Adam

Oh FFS: Updater 4 hosed my Apache config

G'day
Well here's irony.  I did not follow my own instructions and did not take a back-up of anything before running the new updater. And now my Apache config is hosed, and I am feeling rather dumb.  And rather annoyed at the Adobe ColdFusion team. Or whichever of them are responsible for WSConfig, anyhow.

Friday, 2 November 2012

ColdFusion: Problem with session replication with CF10 clustering

G'day:
This is a quick one, just an appendix to yesterday's article about ColdFusion 10 instance clustering. You might recall I was having problems getting sessions working, and that lead on to a discussion about how to get session replication working on a CF10 cluster.

Well I think I have spotted a problem.

Here's the cluster-edit screen on ColdFusion 9 (9.0.2):



And here's the equivalent screen on ColdFusion 10 (10.0... oh, I dunno... I've got updater 2 installed):


Do (maybe) install the new ColdFusion Updater 4

G'day:
This is a follow-up to my earlier article "DON'T Install the new ColdFusion Updater 3".

Update 4 is now out (accompanying blog post from Adobe).

I was gonna say "DO install the new ColdFusion Updater 4", but... do you know what?  Unless there's something really important you need in it, my advice would be to wait for other people to install it first, and see how they go.

Comments

G'day:
Hey, a bunch of people - including myself - have been caught out by a quirk of how the Disqus commenting system that I'm using on this blog works.  If you want to get notifications of responses to any comments you make, you must make the comment via the "Register with Disqus" option (the next step after "Or pick a name..."), rather than the other "Connect with..." options like Twitter, Facebook etc.  I think this is inadequate, and I am doing two things about this:

  1. Hitting Disqus up to see if there's a way around it (although I've read a bunch of their docs and googled rather a lot, and it seems not), and if not;
  2. migrating the comments onto a different system.
But in the interim, if you want to know if anyone has responded to your comments, you need to use the Disqus option.  Sorry.

Righto.

--
Adam

Thursday, 1 November 2012

Things I'd never looked at before: ColdFusion 10 instance clustering

G'day:

This might well be one of those "stating the obvious" kinda posts, but this one's all about me deciding to have a look at what the "Cluster Manager" option in CFAdmin in ColdFusion 10 is all about.  I've never looked at it before, so I'm pig-ignorant about it.  Perfect for the topic of a blog article then, eh?  Heh.

Where to focus Adobe's efforts to improve CFML's CFScript coverage

G'day:
It's time for another survey. This time it's about where Adobe should focus its improvements to CFScript for ColdFusion 11.

Update:
This survey is now complete. The results can be found here.

CF11 is around the corner, so this is perhaps a good time to think about where we (as the community) think efforts should be put into improving CFML.  I've always been a huge "advocate" of CFScript for non-view code, and have always preferred it to tags.  I think tags have their place, but that place is seldom in business logic; they're great for view logic though (ie: mungled up with mark-up).

Wednesday, 31 October 2012

ColdFusion shared hosting

G'day
Sean made an interesting comment on yesterday's article about enhancing logging in ColdFusion.  It's unrelated to that particular topic, but it's worthy of discussion, so I'm going to lift it out and replicate it here, and then put my oar in.


Here's a direct link to the original comment (and my response, and Sean's follow-up) is here.  I'm going to abridge things here, just to focus on what I want to discuss.  I will not abridge it in such a way as to change the context of what either of us were saying.

Tuesday, 30 October 2012

Improvements to ColdFusion's logging

G'day
This is the result of a random thought I had overnight in response to a challenge I have accessing the logs my code creates on my shared-hosted ColdFusion account with cfmldeveloper. This is my first foray into needing stuff hosted somewhere - I've not done any non-work code that I wanted to be public-facing before - and I'm finding it an interesting experience not being the master of my own rig.  I don't mean "interesting" as code for "it sux", I do mean it as "interesting".  No problem has been insurmountable yet, but I have had to revise a coupla the things I automatically do as a matter of course.

Monday, 29 October 2012

@CfmlNotifier

G'day:
I've finally sussed out how the Twitter & Bitly APIs work, and found time to knock-together a Twitter-based ColdFusion / ColdFusion Builder bug notifier.  It polls the Adobe bugbase every coupla hours and see if there's been any new activity since its last poll, and updates its Twitter account's status with the bug headline and a link to it.  So if you want to keep track of new bugs in the bugbase, then "follow" CfmlNotifier.

Thursday, 25 October 2012

Railo via IIS

G'day:
This is just some feedback from a comment someone made on this blog at some point to the effect that "getting Railo to work with IIS was a nightmare" (paraphrase).  I can't actually find the comment now, so you'll just have to take my word for it. I do know that someone else I was talking to today or yesterday also said much the same thing.  And there was a thread on the Railo Google Group in which someone was bleating about this or similar too (I just glossed over it, as admin stuff bores me rigid). I was concerned there was some substance to this, so decided to check for myself.

Here's what I did:

Wednesday, 24 October 2012

Sending "Tweets" via ColdFusion (via Twitter4J)

G'day:
I'm writing an application than needs to send Twitter status updates.  This is an augmentation of the ColdFusion Bugs RSS feeds I have (in the box on the right); I'm gonna send tweets out when a new bug is raised as well.  Or that's the idea.

To do this, I need to work out how to send Twitter status updates (which sounds much less daft than "tweets") from ColdFusion somehow.

This is probably well-trod ground, but the CF-based resources I initially found are all out of date, so I thought I'd post the results of my investigations here in case they're helpful to anyone.

Tuesday, 23 October 2012

Hello (Coldbox) world - abridged: code only

G'day:
As alluded to yesterday, I'm posting this as a distillation of just the results of my investigations, without all the blather as to how I arrived at these results.  This'll make it easier for people to see just the code, should they want to.

The full narrative is in yesterday's article.  There is no additional material in this that was not covered y/day, so there's no need to read it.  It's here just for reference.

Monday, 22 October 2012

Hello (Coldbox) world

G'day
OK, so having polled people as to what their thoughts were as to what framework I should investigate, here I am starting my Hello World "project" (that's bigging it up: I intend to get a page that says "Hello World" created, as a first step).  And I'm typing this blog article as I do so.  Very James Joyce and stream-of-consciousnesss indeed.  Except I'll use punctuation and what I write might be comprehensible.  And first year uni students will not be made to read this thing and write essays on it for years to come.  So not much like Joyce at all.

Sunday, 21 October 2012

CFML: Organise yer apps properly

G'day
This is kinda a follow-up / continuation of the article I wrote the other day on how a request/response comes together, from the client browser initiating it, through to ColdFusion servicing it, and back to the client browser again.

It also stems from me opting to rebuild my PC over the weekend (started on Friday... it's pretty much done now: Sunday afternoon), and therefore reinstalling ColdFusion and getting all my apps up and running again. For those that had a laugh about me running Vista before, I've just upgraded to Windows 7, which garners less derision from those who... for some reason give a shit about that sort of thing.

Friday, 19 October 2012

The CFML request/response process

G'day:
Every month or so I see someone asking questions along these lines:
  • I've set a variable in JavaScript, but my CFML code cannot see it.
  • I've got some CFML code in a variable, but when I output it it just appears on the screen, it doesn't execute.
These appear on the Adobe ColdFusion forums fairly frequently, or less often on StackOverflow.

In response to these I usually trot out a description of processes taking place when a request is made, and "the CFML server runs on the server and JavaScript runs on the client" and all that sort of rigmarole. And I type it in again each time, and it has either a lot of detail, or bugger-all detail depending on my mood at the time.

I've not had one of these for a while, so I'm about due.

Thursday, 18 October 2012

DON'T Install the new ColdFusion Updater 3

G'day:
Adobe did a good job of promoting the release of the new ColdFusion Updater 3 yesterday, but have not done such a good job of promoting the fact it's got a serious bug in it, which - really - should stop people from thinking of installing it.

The bug is that ColdFusion will erase all scheduled tasks every time it is restarted. So this will be a problem for a lot of people.

Update:
Update 4 is now out, and this fixes all the problems in update 3.  That said... I recommend standing back and waiting for other people to apply it and see how they go before you dive out and install it.  "Once bitten..." etc.


I'm just writing this blog entry in a feeble effort to try to warn people against installing this updater until the fix comes out, to stop people from potentially wasting their time.

If poss, can people pls circulate this info.  I've asked Rakshith @ Adobe to do the same.

Cheers.

--
Adam

Wednesday, 17 October 2012

Your IDE of choice: survey results

G'day;
I almost forgot about this one, what with all the flurry about what framework I should use, and trying to actually make some headway with it.

But there was that last survey I solicited: what IDE do y'all use.

So I've closed that one off now, and here are the results.  Cheers to the 73 people who responded to that.  That's the best participation I have had so far (which is good that it's the best response; not so good that the best response I can garner is 73 people! Not to worry: I'm not here to win any popularity contests ;-).

Tuesday, 16 October 2012

New CF10 patch and new CF10 version number

G'day:

Warning:

Do not install this updater if you use scheduled tasks.  See bug 3348026. Adobe are on the case, and will - no doubt - have a fix shortly.

You might remember me banging on about how Adobe messed up the version numbers of ColdFusion 10 when they started doing "updater" releases, but weren't changing the version number to match what they were calling the releases (so Updater 1 which they were describing as 10.0.1 was still listing as 10.0 in CF Admin and the server scope).  I raised this as bug 3323518.

Well they've just released another updater today (10.0.3), and I'm pleased to say the version number now reflects the same thing as the name of the updater.

Monday, 15 October 2012

Probable backwards compat bug in CF10's cachedwithin behaviour

G'day:
I'm following up a post I noticed in the Adobe ColdFusion Forums. I'm gonna write up my findings here, and then summarise / crosspost back to the forums, and perhaps raise a bug depending on what people think about it.

The general gist of the situation is that CF10's query cache seems to be bound to an application, whereas it never used to be. I can see an argument both ways for this, but it's something Adobe seem to have arbitrarily changed without telling us (I have not looked, but the person posting on the forums has, and has drawn a blank).

Update:
Rob Brooks-Bilson has pointed out that there's an Application.cfc setting that controls this:

<cfset this.cache.useinternalquerycache = true>

That about solves this one, except I think TRUE should have been the default. Mileage might vary on that one, I guess.

It's also not been documented in a fashion that's particularly easy to find, I think.  Oh well: at least it's not a bug!

Cheers for that, Rob.

Sunday, 14 October 2012

I've picked a framework. Well: you've picked it for me (UPDATED)


G'day:
Right, so it's 07:45 on Saturday, I've been up since 05:00, and I'm at LHR sitting at the gate for my fortnightly trip to Ireland to see my son. And I've got an age to wait before boarding, so I'm gonna get as much of my article written as I can on which framework you've decided I should use (based on me following the groupthink).

Firstly: thanks everyone for filling-in my frameworks survey: it got over 50 responses - and fairly quickly - which is great. I've parked it now.

Here's the analysis of the breakdown.

Oops
Thanks to Seb (in then comments) for pointing out some errors in my analysis.  It seems that in the process of transferring data from various devices and apps I'd copy and pasted some stuff incorrectly.  And I concede I did not recheck them before committing them, which is a bit of a schoolboy error.  I'm glad someone is paying attention to what I'm doing (as I'm clearly not!).

So, anyway, I'm updating the results below (and will indicate clearly where they've changed).

One thing to note... the bottom line now has me using a different framework than I had indicated I was going to yesterday...


Thursday, 11 October 2012

Thanks Dave Harris: a footnote about getMetadata()

G'day:
I'm following up on some comments people have left against various articles I've written recently: cheers for the thoughts / advice / general input, everyone.

I've updated my article about creating a query and populating it with data in one fell swoop in CF9 to reflect a tip Brian Swatzfager offered me, and tested out some UTF-8 stuff that Nik Stephens reminded me of in my article questioning what Adobe were thinking with their implementation of pageEncoding.  Thanks for the input you fellas.

However something Dave Harris (with whom I used to work, back in NZ) said in response to this article about my expectations of how getMetadata() works warranted a brief article of its own, to get it onto people's radar.

Typos all over the place

G'day:
The quickest one ever.

CFML: Clarification (in my mind) as to how this.[various settings] work in Application.cfc

G'day:
This might be another one of those "Adam states the obvious" articles. Sorry, but I freely admit two things:
  1. not to know everything already;
  2. to be a bit slow on the uptake sometimes.
So if you fall into those categories too, then maybe this will be worthwhile to read. Apologies to the rest of you.


One of the good things about helping out out on various ColdFusion forums is that the problems people have are not necessarily based on things I find myself doing on a regular basis, so encourages me to consider different approaches to things, and to think outside my own personal box. And this means I broaden my exposure to various facets of ColdFusion that I might not normally be exposed to. I would say I've learned more about CF by helping people solve their challenges than I have from my day-to-day work or any amount of reading blogs or articles detailing other people's investigations. That's not to say you should immediately stop reading... hey... aah... come back!

Ahem. Anyway.

Yesterday a person with the rather interesting name of Aegis Kleais was having a challenge with application-specific custom tag paths. The full thread is here, but it's long and drawn out, so I'll summarise it all below to save you... um... clicking on a link and reading the original.

Oh, before I start, I'd like to personally acknowledge Jason Dean's help and persistence on the forums. Jason's one of the more-clued-up ColdFusion community members out there, so it's an excellent asset to Adobe's forums that he mans-the-pumps there (as it were). I also like Jason's style because - and he might disagree with me here - he can be almost as grumpy as I tend to be, and doesn't shy away from having and expressing a strong opinion when he has one.  Cheers Jason.

Right, what was Aegis asking about?

Aegis (I'm gonna steer clear of personal pronouns unless I get the wrong gender...) was investigating the usage of per-application custom tag paths.  Just some background here.  In the olden days (like up to and including CFMX7 I think) the only place one could set a custom tag path was in CFAdmin, which is a server-wide setting.  These days they're settable in Application.cfc, with the this.customTagPaths setting.  Aegis was leveraging this application-specific approach and had mapped a directory, then called a custom tag on a subsequent line of Application.cfc.  But it was erroring: it just wasn't finding the custom tag file.  If the tag was placed in the same directory as Application.cfc, it ran fine. If the tag call was placed in one of the event handlers within (eg: onApplicationStart() or onRequestStart()), it worked fine.  So it wasn't a syntax or pathing issue.  Weird.  I verified this behaviour on CF8->CF10, and Railo too.

This initially flumoxed me, and I was about to suggest it was a bug when something occurred to me, and I had a watershed moment when I suddenly worked out how Application.cfc works in regards to all those this-scoped settings we use.

I thought about any other code I might run:

component {
    this.foo = "bar";
    
    // other stuff here
    
}

That code sets a variable, this.foo.  That's all it does: sets a variable.  No other action takes place.  I might subsequently do something with that variable that makes excellent stuff happen, but that's not what's happening there.

So what's this code doing:

component {

    this.name            = "myApplicationName";
    this.customTagPaths    = "/path/to/the/custom/tags/";

    public void function onApplicationStart(){
        // stuff
    }
    
    // etc

}

We all recognise this as an Application.cfc file, but it's still just some CFML code, so what is this line of code doing:

    this.customTagPaths    = "/path/to/the/custom/tags/";

It's setting a variable.  That's all it's doing.  It does not say this:

    setCustomTagPaths("/path/to/the/custom/tags/");

If it was saying that, we could reasonably conclude that subsequent to that line of code any custom tag calls would find tags in  /path/to/the/custom/tags/.

But all it's doing is setting a variable.

So I found myself thinking, "OK, what's going on then?  How does this all work?"

It occurred to me that it seems like - under the hood - the ColdFusion server is doing this (pseudocode):

appSettingAndHandlers = new Application() // ie: instantiating Application.cfc

theApp.setName(appSettingAndHandlers.name) // because name was set as this.name, it's exposed as a public variable
theApp.setCustomTagPaths(appSettingAndHandlers.customTagPaths) // use the exposed value for customTagPaths to actually make the custom tag paths
//etc

if not theApp.started() then
    theApp.start()
    appSettingAndHandlers.onApplicationStart()
/if
// etc

So what happens is - the same as any other CFC instantiation - the "calling code" (which is within the inner workings of the ColdFusion server) instantiates Application.cfc, which causes all the pseudo-constructor code to run, and then it accesses the settings created in that code to perform various other actions / config / settings etc.  But the crux is that just like when we instantiate a CFC then use it, all the pseudo-constructor code completes before anything is done with the values. This makes sense. Doesn't it?

This actually explains a situation  had in the past wherein I was creating an application-specific mapping with this.mappings, then trying to use a path leveraging that mapping in my ormSettings.cfcLocation value.  And for the same reasons, this did not work.

Anyway, with a combination of Aegis's own investigations, and guidance from Jason any myself,the problem was sorted out.  And I now know something new.

Cool.

--
Adam

Wednesday, 10 October 2012

Why? Just... why?

G'day again.
I'm double-posting today as I spotted this whilst writing up the example code for the previous article.

Thanks to the Maori days of the week having a macron over some of the As, I need to give the ColdFusion compiler a bit of a nudge to explain to it to treat the source code file as UTF-8, not the default of [whatever it is]. It's a bit sh!t that one still needs to do this in the 21st Century, given even NotePad.exe can determine the encoding scheme of a file without being explicitly told, but such is the ways of ColdFusion (view for this bug please: 3342141!).

Constructing a query with data in one fell swoop

G'day:
A coupla quick ones today.

An unglamorous but handy bit of functionality was slipped into ColdFusion 10. When using queryNew() to create a recordset, one can now as the data for it in the same statement. There's two formats for this:

Tuesday, 9 October 2012

getMetadata(): expectations management

G'day:
Just a quick one.  Have a look at this code:

Missed marketing opportunity?

G'day:
This is more on the "CF10 in the UK" thing that I wrote about recently.  First things first, I'm gonna reproduce a comment Rakshith made against one of the other articles here, so as to clarify things:

Hey guys, I was not referring to UK when I said 'over there'. UK was never in the context of this conversation. I was referring to <cfmldeveloper>.<com> and not UK. My bad that I should have just said <cfmldeveloper>.<com> than saying 'over there'. Sorry for the confusion.

P.S. I have better access to data than anyone could possibly have to make a ridiculous claim that Adam is the only in UK using CF10 :)

Sunday, 7 October 2012

No I'm NOT the only person in the UK using CF10!

G'day:
OK so that title seems like I'm stating the obvious, but it's a reaction to my earlier article which questioned whether I was. I was questioning this because Rakshith from Adobe had suggested I was, as far as he knew. I didn't believe him, so I decided to try to find out (by running a survey).

Firstly: thanks to everyone who responded.  I got 56 responses which is quite good for the surveys I run.

Secondly: yes, I can confirm that there are people in the UK other than myself using CF10.  Phew.

Probable significant bug in ColdFusion 10's (and Railo's) RESTful web services

G'day:
Whilst waiting in the virtual queue to book my Glastonbury ticket this morning, I decided to review the new bugs raised for ColdFusion 10, over night. There's nothing better than sitting in front of my PC at 9am on a Sunday pressing refresh-refresh-refresh on six different browsers trying to buy a ticket for a festival that hasn't even announced its line-up yet, and doesn't even happen for another eight months. Still: after 90min of hammering my "reload" buttons, I had parted with my £50 deposit, and I'm all sorted for Glasto next year.

Anyway, this is not a post about mud and drugs and a looming sense of "am I too old for this?", it's about the safer territory of bugs in ColdFusion. And Railo.

Saturday, 6 October 2012

Enough with the Surveys, Cameron! This time: frameworks

G'day
Yeah, sorry, I'm going to ask you to do yet another survey (update: I've stopped collecting results for this, and have done the analysis on it in this article).  I'll stop for a while after that.  Unless I think of something else about your practices I want to find out about, I mean ;-)

Unlike the other ones where I want to simply get a sense of the zeitgeist (and perhaps get it onto Adobe's radar), this one is to help me out with my dev work.

Friday, 5 October 2012

How 4 can equal 3 (or possibly 5) in ColdFusion

G'day:
This was the article I was meaning to write today, but I got sidetracked with the IDE survey thing (I've got 30 replies so far: thanks!), and this took a while longer to nut out than I expected.  Plus work gets in the way sometimes (it's lunch time now... my tech leads reads this stuff, so I figure I had better mention that ;-).

OK, so thanks to my new CF bugs RSS feed I now know all about the new CF bugs that get raised as they happen.  This has been helpful for me twice already (in the space of 48h), so I'm pleased with that.

Today I got notified of 3341284 being raised, which is very similar - but not the same, as it turns out - as a bug we're experiencing in CF9.  So it got my focus.

The short version is that when one uses the argumentCollection to pass arguments around, it can screw up your arguments scope.  So this is quite serious.  This problem first cropped up in CF9 (not CF10 as per the bug report), and persists in CF10.  It's fine in CF8.  And in Railo.  And in OpenBD.

What CFML IDE do you use?

G'day:
This article / question was prompted by a few things. I've been using CF Builder since before it was first released (one of the benefits of bring on the Pre-release Programme), but have had a mixed experience with it, so I'm always questioning its merits, and listening to what other people have to say about it.

Wednesday, 3 October 2012

RSS Feed for 50-most recent ColdFusion Bugs

G'day:
As per my previous article, here's the feed URL: http://adamcameroncoldfusion.cfmldeveloper.com/cfbugs/adobeBugRss.cfm. I'll also put it in my feeds box over on the right.

Hopefully this is useful for some people.

Update:
I've done the one for the equivalent feed for ColdFusion Builder as well now:
http://adamcameroncoldfusion.cfmldeveloper.com/cfbugs/adobeCfbBugRss.cfm


ColdFusion (/Builder) most recent bugs feed

G'day.
For all intents and purposes, the Adobe bug tracker is one-way traffic: one raises a bug... and that's likely to be the last interaction one has with Abode on the topic of that bug. That's not to say that Adobe don't address the bug in some way shape or form, but the humans at Adobe often don't feed back on the bug tracker in a very helpful fashion, and even if they do: there's no notification system, so one pretty much needs to come back on a regular basis to check if there's been any updates to a ticket. This is made slightly unfeasible because Adobe's reaction time to most issues is absolutely glacial compared to the likes of Railo. So checking on a regular basis is generally a fool's errand.

Tuesday, 2 October 2012

I'm the only person in the UK using ColdFusion 10???

G'day:
Sorry for the attention-grabbing headline, but it's not a complete work of speculative fiction (although I kinda hope it is).

Native event framework for ColdFusion 11 ?

G'day:
ColdFusion 11 development is - apparently - underway, so I've turned my mind to what I'd like to see in CF11. One of the things I have been trying to do (with very limited success, I hasten to add) is to learn some new languages. Both with a view to moving on from ColdFusion development eventually (be that via jumping, or being pushed...), as well as it being useful to know how other languages do stuff, and bring some of those techniques back into one's day-to-day work.

Saturday, 29 September 2012

valueList(): bouquet for OpenBD... play catch-up, ColdFusion & Railo

G'day:
One of the most curious things about CFML is the valueList() function.  As far as I know, it is the only function in all of CFML for which the argument must be of datatype "Query Column" (please let me know if there are any other examples?).   The Query Column (coldfusion.sql.QueryColumn in CF,  com.naryx.tagfusion.cfm.engine.cfQueryColumnData in OpenBD, and I can't coerce Railo into considering query["column"] a column like I can in CF and OpenBD, so I can't tell you what Railo the Railo class is... Railo just says it's a string), is - unfortunately - not a very well-realised data type in CFML.

Friday, 28 September 2012

Thursday, 27 September 2012

Survey Results: How ColdFusion updaters should handle CF's version number

G'day
I ran a survey a while ago entitled "Which version of ColdFusion am I actually running?", which was in reaction to Adobe not updating the CF10 version number when ColdFusion "10.0.1" 9as they have been referring to it as) was released.  I had observed in bug 3323518 to them that they neglected to update the version number, to which Rupesh responded along the lines of "oh, we did that on purpose, so it's not a bug".  Err... no, Rupesh: just because you did something on purpose does not mean it's not a bug.  For a start, Adobe has well-documented how version numbers are supposed to be handled, and yer not doing it the way your bosses have told you too.  Secondly: to claim that something that is called "10.0.1" should actually have a version number of "10.0.0" is just daft.  Fortunately cooler heads have prevailed - Hemant (scroll down to his comment) and Rakshith's - and they've agreed that this needs fixing.

Wednesday, 26 September 2012

Callbacks, function expressions, IIFEs, delegates (OK, and closure I s'pose)

G'day
Right, so after a coupla delays, here's the article I threatened you with that's not about closure. Obviously it actually is going to mention closure, but consigned to an afterthought (where, IMO, they kinda belong).

So what is it about? Well it's about a technique that's been possible in ColdFusion since CF5 but is not obvious so is under-utilised, a handy new syntactical construct that was added in CF10, and another one that should have been in CF10 but isn't, something for CF11... and a footnote.

Tuesday, 25 September 2012

I RTFM again, and learn something about evaluate() I didn't really know

G'day
Here's a quick one: I have 17min before I need to start work.  Tick tock.

The title of this is slightly misleading... I wanted to mention "evaluate()" because it's a controversial function, so the title would garner interest.  Whilst this involves evaluate() tangentially, it's more about a slightly-less-derided function precisionEvaluate().

15min.

Monday, 24 September 2012

Not what I was intending to do today

G'day:
I'm back in a cold, wet London after a rather sunny (if quite cool) weekend in Ireland.  And I have a day off work today to recharge my batteries a bit after all the planes, trains & automobiles in the last coupla days.

I was going to write an article "not really about closures" today, but I got sidetracked whilst looking at StackOverflow, and ended up doing something else instead.  It's just a function to convert a number from one arbitrary base to another arbitrary base, and I pinched the algorithm from someone else, but I quite like it so I'm gonna share it here.  And I'll submit it to CFLib too, as  - surprisingly - they do not already seem to have a function to do this.  Weird: I thought everyone has written one of these at some point or another (I know it's about the third time I have written a variation on this theme).

Saturday, 22 September 2012

CF on Windows 8 and Java 7

G'day
I am sitting in a pub in Portumna, Co. Galway, in Ireland.  Drinking a... [I can't bear to say this]...a Coke.  This is the first time I have been to Ireland and I won't be allowed to have a Guinness. This is a crime against reality.  ("Doctor's orders" in case yer wondering).  I mention this solely because a problem shared is... supposedly... a problem halved. What a load of ballocks.

Anyway, all that is besides the point.

Just in case you weren't hanging on every word on the #ColdFusion tag on Twitter today, I hit Rakshith up about what the story is with two things.

Firstly, I asked for clarification about when CF10 will be installable on Windows 8.  He responded (very quickly, thanks Rakshith!) with a blog article, over here.  The short version is "3-5 months".  Given Windows 8 is due out... what: any day now?... OK, just over a month away according to Wikipedia, that's a bit later than I expected.  That said, it will not affect me one bit (I'm still on Vista on one machine, and only just on Win7 on the other).

The next question was about CF9 and CF10 being certified on Java 7 (Java 6 will be EOLed in Feb next year), and his response (Twitter-only this time) was "support for #ColdFusion on Java 7 will come out before Java 6 gets EOLed in November."

Note: I only just now found out the EOL on Java 6 has been pushed out to Feb 2013 (apparently this will be news to Rakshith too...)

Well I hope it's closer to Nov than Feb, to be honest.  It's one thing for Adobe to get there just under the wire with ColdFusion, but please bear in mind all of use need lab time for our server upgrade testing too.  So having a coupla months leeway would be rather handy.  If Adobe are targeting Nov, then that's cool.

This is a pretty short post (for me), but I'm typing on a dodgy old netbook in a noisy pub (the only place in Portumna I've found with Wifi), so it doesn't lend itself to in depth research.

Time for another pint.  Of Coke.  Sod it.

--
Adam

Friday, 21 September 2012

expandPath() weirdness

G'day
I had an odd one today.

I was getting some weirdness with this code:

dir            = expandPath(".");
baseDir     = expandPath("/");
relativeDir    = replace(replace(dir, baseDir, ""), "\", "/", "ALL");
cfcPath = replace(relativeDir, "/", ".", "ALL");


Thursday, 20 September 2012

FFS RTFM

G'day:
So I'm back at work after a week off, and needed to drag myself out of bed a coupla hours earlier than I had become used to, and it's bloody cold today.  So my default setting today is "pissed-off" (so: same as usual, for all intents and purposes).

Wednesday, 19 September 2012

But wait...

... there's more.

CFML:Curious behaviour with THIS-scoped variables in onSessionEnd and onApplicationEnd

G'day
This article stems from a question that came up on StackOverflow today. In summary the bod wanted to know if they could set this.datasource conditionally on a CGI variable, and I confirmed they could, eg:
  • if the cgi.server_name equals "www.firsturl.com" => this.datasource = "firstdsn"
  • if the cgi.server_name equals "www.secondurl.com" => this.datasource = "seconddsn"
My initial response (beyond "just try it and see") was to confirm it was possible.


Someone (called "nosilleg") followed my answer up with  a warning that there could be unexpected results if onSessionEnd (etc) was to use the this.datasource value, as the CGI scope wouldn't be there, so which DSN would be used?  Good question!

To clarify... normal requests all instantiate Application.cfc, and run the pseudo-constructor code to create all the this-scoped config variables, and the CGI variables will all be there so logic predicated on them will work: that's fine.  But things like onSessionEnd() and onApplicationEnd() do not run via a request, per-se, so they won't have any CGI variables.  So what will happen?

This was - of course - my cue to slap together some test code and log stuff and run requests and all that sort of malarky, and now you have to endure reading about my findings.  Well don't say you weren't warned.

So I knocked some code together to test this:


And had a test file to request, thus:


<cfdump var="#this#">

The idea here is that I have DSN1 and DSN2 set up pointing to two different DBs, both of which have identical T_TEST tables to write data to.  Conditional on whether I request test.cfm via localhost or testing.local (both point to the same CF instance) I set this.datasource to point to one or the other (via checking CGI.SERVER_NAME).  If CGI.SERVER_NAME is neither of those, they get nowt.

What I was expecting here was for the onSessionEnd() and onApplicationEnd() to error.  I was not correct.  Well I was a bit correct.  But there is definitely fishy behaviour here.

My log file says this:

Start of logIt(). onApplicationStart [localhost] [dsn1]
End of logIt(). onApplicationStart [localhost] [dsn1]
Start of logIt(). onSessionStart [localhost] [dsn1]
End of logIt(). onSessionStart [localhost] [dsn1]
Start of logIt(). onRequestStart [localhost] [dsn1]
End of logIt(). onRequestStart [localhost] [dsn1]
Start of logIt(). onSessionStart [testing.local] [dsn2]
End of logIt(). onSessionStart [testing.local] [dsn2]
Start of logIt(). onRequestStart [testing.local] [dsn2]
End of logIt(). onRequestStart [testing.local] [dsn2]
Start of logIt(). onRequestStart [localhost] [dsn1]
End of logIt(). onRequestStart [localhost] [dsn1]
Start of logIt(). onSessionEnd [none] [dsn1]
End of logIt(). onSessionEnd [none] [dsn1]
Start of logIt(). onSessionEnd [none] [dsn1]
End of logIt(). onSessionEnd [none] [dsn1]
Start of logIt(). onApplicationEnd [none] [dsn1]
CATCH in logIt(). onApplicationEnd [none] [dsn1] [Attribute validation error for tag CFQUERY.] [The value of the attribute datasource, which is currently '', is invalid.]


I've truncated it, but the "proper" request's log entries were made by "catalina-exec-nn" when nn was a number, whereas the onSessionEnd() and onApplicationEnd() entries were made by "scheduler-n" (where n was a number).  This demonstrates the difference between a normal request running and CF doing its own thing in the background to tidy-up sessions and applications.


Note that neither onSessionEnd() or onApplicationEnd() see a CGI.server_name value.  This is no surprise. However what appears to happen is - by magic, it seems - the onSessionEnd() and onApplicationEnd() calls both receive the last value that this.datasource was set to be via a legit "request".  I verified this through more testing I'll not bore you with, but it was always the DSN of the previous request that these handlers used.  However - rather weirdly - despite onApplicationEnd() definitely seeing this.datasource, the <cfquery> tag in Query.cfc did not think it had a default datasource set.  That's an interesting disconnect, isn't it?  Especially given it seems like onSessionEnd() is in the same boat, but its query worked fine.  Oh, I should have said: data when into the DB tables exactly as one would expect, given the DSN setting (other than the error in onApplicationEnd(), I mean).

If I can be bothered (currently: no) I will refactor the Application.cfc to be tag-based so I can use <cfquery> instead, and see what happens.

Anyway, the bottom line here is that nosilleg was right to be cautious here.  However in situations wherein one doesn't need to use the DSN in the tidy-up handlers, the technique works fine.  I'll feed this back to StackOverflow.

And that's it.

--
Adam