Thursday, 31 October 2013

Follow-up: ColdFusion support for OSX 10.9 - fixed

G'day:
Very quickly... I've talked about this twice:
Pleasingly... this issue (3653076) is now marked "fixed/to test" on the bug tracker.

<cfinclude> and JavaScript

G'day:
Yesterday evening on Twitter, Mike Henke asking a quick quiz question:

Before checking the Gist or progressing... answer the question for yourself.

Tuesday, 29 October 2013

Adobe ColdFusion 10 docs now-community maintainable

G'day:
This is good news. I have just been able to "fix" an entry in the Adobe ColdFusion 10 docs!

Sunday, 27 October 2013

Comments

G'day:
This is a quick apology to people who take the time to comment here.

Saturday, 26 October 2013

CFSummit: interesting ColdFusion 2016 stuff

G'day:
Not that I was at CFSummit, but thanks to Tony Junkes, I saw some interesting slides about ColdFusion "2016" (yeah, the next version, not 11) which can only lead one to speculate...

But first a gripe (hey, this is me, remember). Dazzle? Are you trying to make a mockery of ColdFusion, Adobe? This is like some programming newbie who gives themselves the handle "ProgrammingNinja!" or something. It's not up to you to decide how cool you are; it's up to the audience around you. Rethink that bloody name to something less self-aggrandising. And less like something out of TAoPQotD.

Anyway, the interesting stuff...

Road Map

(yeah, sorry, the links are gonna be links to the photos of the slides that Tony took sorry).

Here we have (time to get my table-based layout skill ready):


Future of the web - verticalAreas
MobileEnterprise Mobility
Responsive Multi Screen Content
Modernized PlatformHigh Performance Runtime
Modular Nimble Engine
Enterprise Class Package Manager
Language Revamp
Horizontals
PeformanceSecurityHTML5


OK, so I'm going to ignore the mobile stuff as it'll still be as wrong to be doing it in ColdFusion 2016 as it is in ColdFusion 11, so I simply don't care.

Modular nimble engine

But "modular nimble engine" sounds interesting. Well forget "nimble": that's marketing-speak. But very pleased they're modularising things. But I wonder to what extent? This conversation has done the rounds a lot of times, and I've posted my own take on it as well: "Survey Results: ColdFusion Modularisation". It can only be a good thing though. ColdFusion has become such a cruft-filled monster that it's time it shook some stuff out of the core. I'm all for leaving stuff like <cfform> and <cfclient> as deprecated options, but they should not be part of the core install. People can install them if they want them using the...

Enterprise class package manager

Here's Tony's photo of the slide (I'll spare you my design skills this time). Cool! Hopefully this is like Ruby Gems or Node.js's NPM system (not that I've used the later... I've not touched node.js, but I've heard great stuff about NPM). It's high time for this, and something people have been clamouring for. It seems to have all the key points:
  • A portal/registry to list all packages available
  • an organization (excuse my ghastly American spelling... I'm quoting this) - a custom package registry
  • CF Developers - easily contribute to this registry
  • info about package exposed as a REST webservice
  • Configure multiple registry URLs
That sounds... perfect. I guess the "Organization" bit is like a sub-registry. So Adobe will maintain an official one, but people can also maintain their own ones? Say for example Ortus want to have BoxManagerBox or something for all their... boxes. Seems reasonable.

Language revamp

(Tony's first photo; second photo; third photo).This is a monster. Check out all the bullet points:

  • Focus on optimized performance on JVM
  • Breaking backwards compatibility
  • Anything with quotes is a string, scope search
  • Increased support for OOP - retain simplicity
  • Tighten interface implementation
  • Collection datatypes
  • New logging framework
  • Create WAR and deploy anywhere
  • Image manipulation revamp
  • Extending the language
  • Concurrency
    • Existing support - CFTHREAD and CFLOCK
    • Synchronized functions and blocks
    • Concurrent data structures
    • Atomic variables and non blocking IO
    • Inherently concurrent - Actor model
What a mountain of stuff!

Unit Testing / TDD - why you shouldn't bother

G'day:
Here's the second in my intended series covering unit testing and TDD and anything else that springs to mind. Earlier in the week I started the series intended to get straight into code, but my intended "intro paragraph" ended up being an entire article, which was then retitled "Unit Testing - initial rhetoric".

So I'm not looking at code today, instead I'm gonna look at why you oughtn't bother doing unit tests.

Huh? Yeah, that's an odd thing to suggest in a series about unit tests, innit? Well let me be abundantly clear now that I'm below the fold, and you're reading the article and not just reading the intro: there are no bloody reasons why you shouldn't unit test. And you're a muppet if you think there are. I should add that I'm not having a go at people who thusfar haven't been doing unit testing etc for whatever reason, but those people generally know they should have been doing it, but haven't for [some reason which they probably concede is invalid]. I'm only having a go at people who try to justify their position as being a valid one.

Friday, 25 October 2013

Adobe backtracks on no-support for ColdFusion 10 on OSX 10.9

G'day:
I mentioned this the other day: 'So there won't be support for OSX 10.9 "Mavericks" on ColdFusion 10'. I just checked the bug tracker, and ticket 3653076 has now been marked "To Fix". Hopefully they mean "for ColdFusion 10" (and, realistically, they should fix it in CF9 too, as it's still a supported version of ColdFusion), not just for ColdFusion 11.

Good work to two groups of people:
  • the community, for rounding on this issue and making their voices heard. The ticket's only existed for three days, but it's got 33 votes and 20 comments. That's very active for a ColdFusion issue;
  • the Adobe ColdFusion team for seeing sense in this matter.
Yay everyone!

--
Adam

Thursday, 24 October 2013

<cfclient>

G'day:
CFSummit 2013 started today - I'm quite jealous of everyone who's there btw - and Adobe opened with a variation on their keynote they used at cf.Objective(), SotR and CFCamp, which covers some of the new stuff in ColdFusion 11. And, naturally, they spent some time on <cfclient>. And then if I'm reading my Twitter feed and the schedule correctly, after the keynote they did another presentation looking more closely at the technical side of new features, including some <cfclient> code. And there was an eruption of Twitter traffic on the topic of <cfclient>. Personally, I think the whole idea of <cfclient> is a blight on CFML, and demonstrates Adobe have learned very little since those "heady" days of <cflayoutarea> and <cfpod>.

So there won't be support for OSX 10.9 "Mavericks" on ColdFusion 10

G'day:
There's been a huge flurry of activity on the ColdFusion Bug tracker around ticket 3653076, entitled "Bad apache / tomcat connector for Mac OSX Mavericks 10.9". It was raised two days ago and has 20 votes already, and 13 comments.

And Richard Herbert has just done the decent thing and reminded us all that Adobe have already officially responded to this...

Wednesday, 23 October 2013

Documentation for older versions of ColdFusion

G'day:
Gavin was asking about docs for older versions of ColdFusion today. In my searchings, I've located the docs for a number of older versions of ColdFusion. I'm gonna list 'em here so they're easier to find.
  • Cold Fusion 2.0 online documentation, courtesy of GES technologies (update 2015-05-07: link is now dead)
  • Cold Fusion 3 online documentation, courtesy of House of Fusion (update 2016-06-30: link is now dead)
  • ColdFusion 4.5 online documentation, also courtesy of House of Fusion (update 2016-06-30: link is now dead)
  • ColdFusion 4.5.2 offline downloadable documentation, courtesy of Adobe (these are zip files)
  • ColdFusion 5.0 offline downloadable documentation (Adobe, zip files)
  • CFMX 6.1 offline downloadable documentation (Adobe, zip files)
  • CFMX 7 offline downloadable documentation (Adobe, zips)
  • ColdFusion 8 online documentation (Adobe livedocs)
  • ColdFusion 9 online documentation (help.adobe.com)
  • ColdFusion 10 online documentation (the current rendition of Adobe online docs: learn.adobe.com. I wish they'd just stick with the same bloody domain name / online docs structure!!). That site is now dead. But the docs are here: ColdFusion Documentation Archive.
  • ColdFusion 11: same page as above, but that's a direct link.
Hopefully that's helpful to someone.

Righto...

--
Adam

    Unit Testing / TDD - initial rhetoric

    G'day:
    I was talking to a mate/colleague the other day @ CFCamp, and the topic of unit tests came around, and that they... well... didn't do any. They were aware this was not good, but had a sorta mental block of how to get going with TDD and the whole idea of test-first code-second. I had to admit I only started doing unit testing in my current role, and I have our lead architect, Simon Baynes to thank for this. For the preceding decade or so of my development career my approach to testing was the standard cowboy approach of if something didn't seem to break it was probably OK. A lot of people take this approach. It's a shit approach. Don't do it.

    In my own defence (it's a lame defence, I hasten to add), I can explain away my lack of unit testing practice for the first few years of my career as I was one of these typical CFML developers who wasn't aware of the wider industry around me, so having not thought to investigate stuff like good coding practices and to check how other people did stuff. Also when new to dev I was in a very jack-the-lad cowboy-ish environment in which doing a decent job of anything was shunned in favour of doing the quickest job possible. Not ideal.

    However ignorance is not a defence, and certainly for a few years after my start I was well aware of unit testing as a concept, but never really looked into it. I was like "yeah, I know I should look at this stuff, but it'll just end up meaning I have to write a whole lot of boring test code, and who wants to do that?" This is a very immature, lacking-in-self-disciple attitude, which I now regret.

    Tuesday, 22 October 2013

    Follow-up to a "not a bug" status from Adobe: arrayFindNoCase() returns false negatives

    G'day:
    About a year ago I raised a ticket observing that arrayFindNoCase() doesn't really work so reliably: 3316776. A coupla weeks ago it was marked as "not a bug", which I find rather bemusing - as there's definitely buggy behaviour - but not as bemusing as the explanatory feedback from Adobe.

    Monday, 21 October 2013

    Best description of Stack Overflow "community" ever...

    G'day
    Someone just left this comment against an older blog article on a similar topic:
    Stack Overflow is basically the Stanford Prison Experiment playing out on the internet.
    Classic.

    --
    Adam

    CFML: Community collaboration: fixing some bugs in my defer() function

    G'day:
    I released a UDF defer() to CFLib and Code Review yesterday. And Adam Tuttle quickly spotted a shortfall in my implementation. And whilst addressing that spotted two more bugs, which I have now fixed.

    Adam's observation was thus:

    you're not doing a thread join in this code anywhere, which means that if the deferred job takes longer than the rest of the request to run, it will not be able to affect the response.
    [...]
    For your function to be useful, either the result of the job function can't be something that's needed to create the response, or you'll need to add a way to expose a join reference for the created thread. 

    All very true. So I mulled this over in my head this morning on the train, and came up with a fix. I also realised I had another significant bug in the original implementation at the same time. And when implementing the fix, spotted another bug. All now dealt with.

    Here's the revised code:

    public struct function defer(required function job, function onSuccess, function onFailure, function onError, function onTerminate){
        var threadId = "deferredThread_#createUuid()#";
    
        local[threadId] = "";
    
        try {
            cfthread.status = "Running";
            thread name=threadId action="run" attributecollection=arguments {
                try {
                    successData.result = job();
                    cfthread.status = "Completed";
                    if (structKeyExists(attributes, "onSuccess")){
                        onSuccess(successData);
                    }
                } catch (any e){
                    cfthread.status = "Failed";
                    if (structKeyExists(attributes, "onFailure")){
                        onFailure(e);
                    }else{
                        rethrow;
                    }
                }
            }
        } catch (any e){
            cfthread.status = "Errored";
            if (structKeyExists(arguments, "onError")){
                onError(e);
            }else{
                rethrow;
            }
        }
        return {
            getStatus = function(){
                return cfthread.status;
            },
            getThreadId = function(){
                return threadId;
            },
            terminate = function(){
                if (cfthread.status == "Running"){
                    thread name=threadId action="terminate";
                    cfthread.status = "Terminated";
                    if (isDefined("onTerminate")){
                        onTerminate();
                    }
                }
            }
        };
    }
    

    Sunday, 20 October 2013

    CFML: Threads, callbacks, closure and a pub

    G'day:
    I'm over in Ireland this weekend, and am doing my normal Sunday afternoon activity of sitting at Shannon Airport drinking Guinness, having finished my business early, so have a 4h wait in departures before my flight even considers boarding. Today's excitement here was the 500-odd US Army squaddies in transit to or from what I presume was Afghanistan. It makes a change from being the only person in the place, which was the case two weeks ago (other than shop staff, that is). Last night I killed some time in the pub too, during which I knocked out some quick code, to solve a problem I invented for myself to kill time. Here's the result.

    A week or so ago Luis started an interesting thread on the Railo Google Group: "Add closure support to blocking operations to allow them to be non-blocking operations.". The summary of which is:

    [...]I propose adding closure callback support to the following functions/operations so they can be processed natively in the background (non-blocking) and then call back when done.

    FileRead
    FileWrite
    [...]
    etc

    Basically any operation that can block a network or local resource.  Imagine doing this:

    fileRead( file, function(contents){
      process file here in the background once it is read.
    });
    [...]
    The bits I omitted ([...]) are simply for abbreviation, and preserve the gist of his suggestion. This is a reasonable idea in general, but - as I go on to say in the thread - I don't think the suggested approach is very good for a coupla reasons. It's not bad, but it just seems a bit "embryonic" to me. But this is fine, this is what discussion forums are for.

    My suggested approach would be more all-encompassing. Why limit this functionality to a subset of predetermined built-in functions? What about other built-in operations that might be slow, but otherwise doesn't need to interact with the rest of the code subsequent to it in the request? What about custom code that is similar? It makes little sense to me to "hard-code" this sort of behaviour to specific operations, to me.

    A better solution would be to provide a general mechanism that can be used by any code to background-thread its execution, and fire callbacks on completion, failure etc, so as to kick off the next process, or flag-up that the process has completed.

    Then it occurred to me that I thought I could knock a solution out to this using a single function. Not a very complete solution, but a solution nevertheless.

    So sitting at the bar last night, over the course of four Guinnesseses, I came up with this lot:

    Thursday, 17 October 2013

    Premature Obsolescence

    G'day:
    An online mate of mine just pointed me at some code he was fixing (not his own, I hasten to add), and drew my attention to some code commentary which made him laugh / cry / scowl / despair:

    CFML: listEach() on CFLib

    G'day:
    This one cropped up because of something Rob Glover mentioned in passing on Twitter, which I gave a fairly perfunctory response to.

    Scott more helpfully pointed out that converting the list to an array and looping that is a good approach. I agree.

    However this got me thinking: a list-iterating UDF would be handy, and CFLib doesn't seem to have one, so I knocked one together:

    public array function listEach(required string list, required function callback, string delimiters=","){
        var arr = listToArray(list, delimiters);
        var arrLen = arrayLen(arr);
        var result = [];
        for (var index=1; index <= arrLen; index++){
            arrayAppend(result, callBack(argumentCollection=arguments, index=index, element=arr[index], length=arrLen));
        }
        return result;
    }
    

    There's nothing exciting here, it just takes a list, loops over it, and passes each element to a callback to process it. It'll return an updated array if that's helpful. I chose an array instead of a list because it's more useful, and allows non-simple values to be returned.

    This follows the precedent set in my recent arraySetEach() UDF, passing all the passed-in args to the callback, plus the position the iterating index is at, and the value, and in this case the length of the list being processed.

    It can be used both to create a new, transformed list:

    numbers = "tahi|rua|toru|wha";
    
    function _ucase(){
        return ucase(element);
    }
    
    upperCasedNumbers = listEach(numbers, _ucase, "|");
    writeOutput(serializeJson(upperCasedNumbers));
    

    Output:

    ["TAHI","RUA","TORU","WHA"]

    Or just as a looping construct. Here we turn the list into an <ol>:

    function toOL(){
        if (index == 1){
            writeOutput("<ol>");
        }
        writeOutput('<li id="index_#index#">#element#</li>');
        if (index == length){
            writeOutput("</ol>");
        }
    }
    
    
    listEach(numbers, toOL, "|");
    

    Which outputs mark-up:

    <ol>
        <li id="index_1">tahi</li>
        <li id="index_2">rua</li>
        <li id="index_3">toru</li>
        <li id="index_4">wha</li>
    </ol>
    

    So that was two examples: using it to create an updated data structure, or simply as a looping construct. Actually the toOL() UDF would probably be better done in tags, given we're outputting mark-up:

    <cffunction name="toOL">
        <cfif index EQ 1>
            <ul>
        </cfif>
        <cfoutput><li id="index_#index#">#element#</li></cfoutput>
        <cfif index EQ length>
            </ul>
        </cfif>
    </cffunction>
    

    For the UDF I'll submit to CFLib (as above) the code is ColdFusion 10 / Railo 4.x only, but Rob was using CF8. However with a few cosmetic changes, this all works fine on CF8 too:
    function listEach(list, callback, delimiters){
        var arr        = false;
        var arrLen    = false;
        var result    = [];
        var index    = 0; 
    
        if (!structKeyExists(arguments, "delimiters")){
            delimiters = ",";
        }
    
        arr = listToArray(list, delimiters);
        arrLen = arrayLen(arr);
    
        for (index=1; index <= arrLen; index++){
            arrayAppend(result, callBack(argumentCollection=arguments, index=index, element=arr[index], length=arrLen));
        }
        return result;
    }
    

    I just needed to change the function definition slightly, do my VARs at the top, and scope my arguments specifically in some places in the calling code:

    function toOL(){
        if (arguments.index == 1){
            writeOutput("<ol>");
        }
        writeOutput('<li id="index_#arguments.index#">#arguments.element#</li>');
        if (arguments.index == arguments.length){
            writeOutput("</ol>");
        }
    }
    

    And that was it.

    It's important to remember that people get confused when talking about closures and callbacks, and often use the word interchangably. And closure is only a facet of function expressions, and only available from CF10 / Railo 4.x. However being able to use callbacks has existed in CFML since CF5, and before Railo even existed.

    None of this is terribly exciting, but maybe someone will find it helpful. Shrug.

    Righto.

    --
    Adam

    Wednesday, 16 October 2013

    CFCamp: Exeunt Omnes

    G'day:
    Richard Herbert and I are sitting in the departure lounge of Munich Airport, awaiting our EasyJet flight back to the UK. I have a beer in hand. Predictably.

    Tuesday, 15 October 2013

    CFCamp: Quick unicode regex code snippet

    G'day:
    A question just came up in Kai's "Regular Expression Clinic" at CFCamp about unicode support in regular expressions. This is important in countries like Germany where they have a lot of non-ASCII characters in regular use in everyday words, eg: letters with umlauts above them ("ö"), or double-S characters ("ß"), etc. I didn't quite know the answer, so I had a look and came up with some code...

    CFCamp: inappropriate imagery in Germering

    G'day:
    No, not the other photo that's doing the rounds. But this one...

    CFCamp: Rakshith's Adobe ColdFusion Keynote: notes of my own

    G'day:
    I fired most of this stuff out on Twitter as it happened, but here's an aggregation of some things that crossed my mind during Rakshith's Adobe / ColdFusion keynote at CFCamp.

    First things first... I was very relieved that there was a big chunk of this presentation showed actual code. This is a huge improvement over cf.Objective() and Scotch on the Rocks wherein the main Adobe presentations were aimed at IT Managers rather than developers, and was just promotional material with very little substance. Rakshith's presentation today was really good. This is not just my opinion, everyone else I talked to said the same thing.

    CFCamp: freebies

    G'day:
    Just doing a bit of multi-tasking whilst listening to Rakshith discuss the new web dev training curriculum (which also apparently includes some ColdFusion stuff). But this article is nothing to do with that.

    Monday, 14 October 2013

    CFCamp: <cfprocessingdirective> and how not to use it

    G'day:
    This is gonna be a quick one. The topic of <cfprocessingdirective> came up today, in the context of I18n, and character encoding.

    CFCamp: Loop labels in Railo

    G'day:
    Here's another one that I already knew about, but hadn't looked at it before. Gert brought it up in his keynote today, so I thought I'd have a look. Railo has added labels to <cfloop> and <cfbreak> / <cfcontinue>. But the implementation is either incomplete or non-intuitve (at least to me).

    CFCamp: new (to me) function in Railo/CFML: serialize()

    G'day:
    Gert gave typically bloody interesting keynote presentation this morning on what's been happening in Railo over the last year or so, where it's at now, and where it's headed for its next version. I might write up that part of it at some stage, but that sort of thing takes a while to write up and requires more concentration than I feel like dedicating at the moment, so I'm just gonna focus on some of the code stuff he showed us.

    First thing... take note, Rakshith: Gert showed us code. Not smoke and mirrors and marketing spiel, but code.

    There was a bunch of stuff that was new to me, and I'll write that up separately, but here's a quick examination of Railo's serialize() function. The docs are here: serialize(), but there's not really any useful information there. What serialize() does is to... serialise data, which can later be evaluated (using, yes, evaluate()) back to CFML data again. Here's an example using an array:

    rainbow                    = ["Whero","Karaka","Kowhai","Kakariki","Kikorangi","Tawatawa","Mawhero"];
    serialisedViaFunction    = serialize(rainbow);
    deserialised            = evaluate(serialisedViaFunction);
    
    writeDump([rainbow,serialisedViaFunction,deserialised]);  
    

    Here we get the output:

    Sunday, 13 October 2013

    CFML: arraySetEach()

    G'day:
    I had a conversation on IRC the other day with Jason Dean about a shortcoming of arraySet().


    The issue is that array set works like this:

    arraySet(array, from, to, value)

    So like this:

    sameStructs = [];
    arraySet(sameStructs, 1, 5, {});
    sameStructs[3].foo = "bar";
    writeDump(sameStructs);
    

    Unfortunately - as you might guess from the variable name - ColdFusion only evaluates the value once - meaning each array element has the same structure. So this code outputs:

    Wolpertinger

    G'day:
    This was in the display case just inside the door at the restaurant last night:


    To which our reaction was "what the f*** is going on in this place?"

    But apparently it's a Wolpertinger. Of course it is.

    I love Bavaria.

    --
    Adam

    CFCamp: PresideCMS goes open source

    Guten Tag
    (and that's the end of the German... I'm over-extending myself even with that much!)

    Alex Dom and I flew from Gatwick to Munich late yesterday afternoon, touching down mid-evening. An hour or so later we were wandering around Germering in the middle of the night with Alex going "I think it's down here... just a bit more... further... still... I think..." (where "it" was their hotel... I was staying at a different one). But after a km or so stroll, we found their hotel, dropped their bags off, and went back to downtown Germering for a meal. Most things were closed (10pm, sure... but it was Saturday night?!), but we found a very traditional-seeming restaurant - Zum Griabig'n - which was still open and serving various renditions of flesh and potatoes, so we settled in. The food was hearty and the beer was perhaps one more than I needed (two at Gatwick, two on the plane, one over dinner), but all was good. I slunk back to my hotel a coupla km down the road, and collapsed in a heap.

    Friday, 11 October 2013

    Server.cfc and onServerStart()

    G'day:
    Another interesting thread cropped up on the Railo Google Group today: Micha was asking about Server.cfc, and how people use it (if at all).

    This is not very widely used code, so I'll link to the docs for onServerStart() and quote a para from it:
    ColdFusion now supports a CFC with an onServerStart method that runs only when the server starts. The onServerStart method takes no parameters, and is the only function in the CFC. The function is useful for application-independent tasks, such as instantiating the applications, configuring logging, or setting up the scheduler.
    By default, ColdFusion looks for the onServerStart method in cf_webroot/Server.cfc.
    Apparently Railo does not offer this functionality. But also have never had anyone notice this.

    CFML: A possible variation on the thread idea...

    G'day:
    I can't take sole credit for this idea, because when reading something Luis said today on the Railo Google Group, I had an epiphany. Let's have a look at <cfthread> (or, indeed, just thread) again...

    Thursday, 10 October 2013

    CFML: CFCamp seems real now

    G'day:
    This is a bit of a time filler because the Central Line is screwed so I can't get home in time for my Skype with my boy, so need to stick around the office and do it from here. Damn you, TFL! Not to worry.

    CFCamp is all of a sudden seeming very real. Mike touched base with me a coupla days ago and has organised my hotel, and EasyJet reminded me today (third time) I had to actually check-in if I wanted to fly with them on Sat. I'm still really really flattered that the CFCamp peeps are comping me to the thing.


    There's been a couple of programme changes since I last mentioned what I was gonna look at.

    Blocked request

    G'day:
    I need some help. I have a situation like this (ColdFusion 9.0.1):

    request.findMe = "here";
    
    function f(string request){
        // get the request scope
        writeDump(var=[request]); // blocker
        writeDump(var=[structGet("request")]); // blocker
    }
    
    f("blocker");
    

    I need to insert some code at "// get the request scope" which creates a reference to the request scope that I can then reference later in the function. I cannot change any other code.

    The above is not the real code, just a repro case that demonstrates the situation.

    NB: I know the situation is less than ideal, codewise, but that is outwith my control.

    Any ideas?

    Update:
    This is resolved. We took the approach that Sean suggests below. I'll update with more info later, but am flat out fixing a bug at the moment.

    --
    Adam

    ColdFusion: Why weI fight

    G'day, and apologies to Frank Capra for trivialising his work.

    An alternative title for this article could be "Readers: can't live with 'em... can't kill 'em". But I liked the Capra allusion which popped into my head initially, even if it does self-aggrandise what I do here "somewhat".

    Can I please remind you lot of something. At the top right of the page you are reading, second paragraph, it says this:
    I tend to be a bit "forthright": I think CF is a good product, but I won't blindly defend it in all circumstances, and I have been quite critical of ColdFusion and Adobe at times. This will come out occasionally here: I make no apology for it.
    It says that on every page of the blog. And I put it there on every page for a reason.

    First: a digression. The back story of this blog - and the gist of the title - is this.

    I have been in the ColdFusion community since about 2001 (working with CF since 2000, but was unaware of the community at the time). I have enjoyed reading the various blogs that have come and gone, but they all and one common thread: they were always - or at least almost always - never in the slightest bit critical or questioning of what Macromedia / Adobe were doing with ColdFusion. The general approach of the CF community seemed to be blind adulation, matter-of-fact stick to examples of how the code worked, or stony silence when something was a bit rubbish. No-one ever seemed to go "Oi, WTF is going on with this?"

    I had been thinking about starting a blog for a number of years, but for a while I was suffering from imposter syndrome, and thought I'd probably only have enough material for about half a dozen posts, and then run out of steam. Plus it would simply not be of any benefit to the community. Plus I have the attention span of a goldfish, and lose interest in stuff fairly quickly.

    But whenever it was - a year or so ago - I decided, screw it... I'm fed-up with where Adobe is taking this community (or more to the point: I'm fed up with that the community seems to be sleeping through this happening), and I perhaps do have an interesting alternative spin on what's going on in the CFML world, so I'll write it down. My position has always been to question what's going on, rather than just sit idly by watching it but not saying anything because I'm too darn polite (like an awful lot of people seem to be). The raison d'ĂȘtre for this blog is kinda "well someone's gotta say something".

    CFLive.net gets a code editor

    G'day:
    I'm just wading through the overnight Tw@tter Chatter, and noticed this from Russ:


    Express Install for ColdFusion 11

    G'day:
    A lot of people have observed ColdFusion could benefit from being quicker to get up and running. I myself have written a coupla articles assessing the situation:
    I also raised a ticket with Adobe: 3370889.

    Well...

    Tuesday, 8 October 2013

    CFML: savecontent update: actually not being implemented

    G'day:
    This is a shame. Last week I reported that my savecontent enhancement request was marked "to fix" (3643125). Unfortunately today the status has been changed to "closed/deferred".

    I still really don't understand Adobe's approach to bug tracking. If something's been "deferred", it should not be closed. "Deferred" implies it's not been handled yet, but will be, whereas "closed" implies that something has been handled, and that's the end of that.  Even if it's deferred until ColdFusion 12, 13, etc, the issue should still be OPEN. But there is an awful lot of things I don't understand about how Adobe manage their bugbase, so no real surprise.

    I don't, btw, have much of a gripe with them not fixing this just yet. I can see how it might be a bit of an undertaking to get block statements to act like expressions, although that in itself is a cool notion! Then again ColdFusion 11 is definitely the correct release to do this work in, if they're trying to draw a line under CFScript coverage. I seriously don't think the way savecontent works currently is correct, and the longer that syntax persists, the more entrenched it's gonna be in people's codebases.

    This also goes to show I need to keep an eye on the tickets they mark as "to fix", as it might not actually be the case they're gonna fix 'em.

    Righto.

    --
    Adam

    Monday, 7 October 2013

    "Not worth the effort" again, from the Adobe ColdFusion team

    G'day:
    Andrew Scott brought this one to my attention. It's what seems to be another example of Adobe finding the "too hard basket" being more convenient that rolling up one's sleeves and actually doing one's job properly.

    Friday, 4 October 2013

    ColdFusion: CLI

    G'day:
    Real quick... A bunch of people have lamented the absence of a command-line interface in ColdFusion (Railo has one, apparently: haven't tested it). But no-one seems to have gone beyond moaning about it.

    So I've raised a ticket for it: 3646258.

    ColdFusion 5 used to have a CLI, and it was jolly handy. I've also been doing stuff with Ruby and PHP recently, and running code from the command prompt is a nice way of running / testing code. And I am daily running Javascript from the console prompt in Chrome... it's just handy. I also think it could help move CFML away from just being a "web language". Well a first step in that direction.

    So I think this would be a cool addition to ColdFusion 11. Or even a fix of a regression issue that's been around since CFMX6.0.

    Thoughts? If you like the idea, go vote pls.

    --
    Adam

    Well - like it or not - it's open source now

    G'day:
    I was awake at 4am for some reason (now after 5am). However answered a question on StackOverflow and stirred the pot a bit on Twitter. This is not a good use of my time though. Earlier today Adobe announced they'd been hacked, and have had a lot of personal details stolen, and the source code for Acrobat, ColdFusion and ColdFusion Builder are now out in the wild.

    Thursday, 3 October 2013

    CFML: savecontent update

    G'day:
    Remember I logged that E/R (3643125) the other day, regarding a suggested enhancement to how savecontent works? The idea was to make it work like this:

    content = savecontent {
        // stuff goes here
    }
    

    Instead of this:

    savecontent variable="content" {
        // stuff goes here
    }
    

    Well it's been marked "to fix". How cool is that?

    Nice one, Adobe. And cheers to everyone who voted for it.

    --
    Adam

    Wednesday, 2 October 2013

    Hang on... what did Rakshith say?

    G'day:
    I was writing the previous blog article about improving thread syntax, and suddenly went... hang on... what? What did you say, Rakshith? And I dug back into his blog article from yesterday "ColdFusion: News and Updates from Adobe"...


    This was buried half way down the article:

    There are quite a few language improvements such as [...] member functions that are already a part of the upcoming version
    What?! Member functions? COOL.

    CFML: Another suggested tweak to CFScript: thread

    G'day:
    Now I think there's a chance I'm having a "senior moment" here (which I hoped I'd not be getting for another 20-odd years, but hey-ho), as I'm sure I've discussed this before, but I can find no evidence of having done so.

    CFScript's support for <cfthread> is another one of those weirdly-syntaxed things like savecontent:

    thread name="t1" action="run" someattribute="value" {
        // stuff here
    }
    

    What I think this should be like is this:

    t1 = Thread.new({someattribute="value"}) {
        // stuff here
    }
    

    Tuesday, 1 October 2013

    Adobe: Observations on Rakshith's recent blog article

    G'day:
    I've just seen Rakshith's Twitter update pointing us to a new blog article from him, "ColdFusion: News and Updates from Adobe".


    This seems to be a response of sorts to Cutter's blog entries recently:
    I'm just jotting down my thoughts. I'm typing this as I'm reading the article.

    Rather than viewing Adobe and community as two separate entities, we are keen to work with the community with a common goal of reviving ColdFusion. And in that context the feedback that we have been receiving is extremely valuable.
    Well this is good news. I was beginning to get the impression that Adobe didn't really care or pay attention to the community, because... well they seldom seem to, and I think they get a lot of licensing revenue automatically, just as large US companies and govt agencies automatically re-up their licences no matter what Adobe to with ColdFusion. So in that light... perhaps they think they don't need to engage with us developers. We don't pay their bills, after all. This is just supposition, but the impression I get sometimes.

    I have to say though, that I think the Adobe team need to put their money where their mouth is. This is the first sniff I've heard from them for weeks. The last entry on the official blog was two weeks ago, and prior to two posts then... a month before that! That's no good. And where are their developers in the community? They need to be part of the community.

    The last entry on Rupesh's blog was in 2010! The penultimate entry is entitled "ColdFusion Survey : We are listening". I note Rupesh's blog runs on PHP, btw.

    Shilpi... the "security tzar"... the last blog entry on her blog was in July: "Slides & Recording of e-seminar on Security Best Practices for ColdFusion".

    Ram? March 2012 was his most recent ColdFusion blog article (taken from "Ram's Blog: My ColdFusion Blogs".

    I could go on, but you get the point: they're invisible. It's the same on the ColdFusion forums, Stackoverflow, Twitter. They are not part of the community. Time you joined in, people.

    Suggested revision to savecontent

    G'day:
    I like that <cfsavecontent> is available in CFScript now, but I dislike the clunky way it's been implemented.

    Scotch on the Rocks 2014: tickets now on sale

    G'day:
    I've got no connection to Scotch on the Rocks other than having attended a few times in the past. But it's a great web tech conference, and I'll be going to it again next year.

    They've just put tickets on sale.

    ColdFusion: Tirade averted... (update: no, actually: tirade)

    G'day:
    Last night someone from the community directed me at this issue on the bugbase: "Updating a task via cfschedule resets task to defaults". Neither of us could believe what Adobe had said to justify themselves. Fortunately in the interim cooler heads have prevailed, and they're on the case, but - dammit - I want to mention this anyhow.

    The story with this bug - and it's a bug, Uday - is this:

    If you are updating a scheduled task via the cfschedule tag it is possible for some of the task info to be reset back to default. For example, if task had an eventhander configured and cfschedule was used to update task but eventhandler attribute was not used then eventhandler would be set to blank. The eventhandler attribute is just one example as this affects other attributes equally.
    So that's a bit rubbish.

    Last night, the response from Adobe - via Uday Ogra - was this:

    This is by design. As this action re-creates the schedule task. For updating particular attributes of an existing task it is recommended to use admin UI
    This is yet another example of Adobe people being bloody jobsworths, IMO. I am gobsmacked by the stunning ignorance of Uday's justification here on two levels:
    • Who cares if it's by design: it's poor, lazy design. I'd be cool with this is Adobe went "oh yeah... oops", but to try to justify this away with "oh, it's meant to be like that" is pathetic. Indeed if you actually went out of your way to design something like that it doubles the question marks over your capabilities here: introducing a bug during development is one thing; specifically deciding to design something this poorly is unbelievable. Do you mean to say you sat down and went "right, when one uses this functionality to do an update, we'll blow away all the settings to didn't specifically set for update. Yeah: that's what people will want". Shudder.
    • What sort of bloody moronic advice is "as an alternative, use the UI". How is that gonna help us in our code? What sort of completely detached from reality suggestion is that? How is it a solution to a coding problem to suggest "use the UI instead".