Showing posts with label Aaron Neff. Show all posts
Showing posts with label Aaron Neff. Show all posts

Tuesday 10 May 2016

CFML (yes, shut-up): sorted struct literal syntax

Yeah, all right. I'm gonna be admonished by at least one of my mates (that's you, Brian) for writing another article about CFML, but... oh well. This is not gonna become a habit as I feel bad writing it.

You might remember that CF2016 promised to have sorted structs. I documented this ages ago "ColdFusion 2016: ordered/sorted structs". One thing you might have noticed is that whilst ordered structs made the cut; sorted ones did not. Adobe's briefly documented the ordered ones here: "Collection support (Ordered)".

To recap: structs in CFML have always been intrinsically unordered collections. If you want an ordered collection: use an array. Structs to preserve an internal ordering, but how that's done is specifically undocumented and one should never rely on it. Previously if one's needed to access a struct's values in a specific order, one's needed to maintain a separate index of what that order is, or just use the sort method to return an array of they keys in a prescribed order and then iterate over that, using each array element value to access the struct. It's all in the docs. The chief problem with sorting a struct was it was only ever based on the keys, and only ever in a lexical ordering. Which is almost never a sensible ordering to use. But this is just the penalty one pays for trying to use an intrinsically unordered data type as an ordered one.

ColdFusion 2016 added ordered structs, and was supposed to add sorted ones too, but sorted ones did not make the cut for release (and that's as much as I can say about that due to NDA reasons). I had pointed out to Adobe that "ordered" and "sorted" means the same thing for all intents and purposes... I don't actually know if they've taken this on board. I hope so, so they don't just look like dicks when they do get around to releasing the sorted variety.

I do feel safe to say they do intend to finish this particular job... I don't think that's breaking any NDA. I cannot say when any updates to ColdFusion 2016 might come out though, as I'm completely out of that loop now. Except for elements of the matter that I will not refer to directly, but you can read between the lines that they're perhaps under discussion somewhere.

Now... the contrived difference in definition that Adobe have invented between "ordered" and "sorted" is that an ordered struct preserves the order in which the keys are added:

person = [firstName="Kiri", lastName="Te Kanawa"];

If one iterates over that, we get Dame Kiri's name-order preserved:

person = [firstName="Kiri", lastName="Te Kanawa"];
person.each(function(key, value){
CLI.writeln("#key#: #value#");


Compare that to a normal struct:

person = {firstName="Kiri", lastName="Te Kanawa"};
person.each(function(key, value){
    CLI.writeln("#key#: #value#");


You see the key order is not preserved.

OK, this is all lovely, but this is about sorted structs. So what's the diff? To recap, a Sorted struct is one in which one can specify the order the keys should iterate in. This is a bit edge-case-y, but one might want to iterate over they values in some different order other than insertion or key-name order. Perhaps alphabetically by value. Or by some other enumeration, or by length of value or something. There's a use case there, even if it's also edge-case.

One of the big challenges with sorted structs is the literal expression syntax for them. You know: array literals are expressed like this:

["tahi", "rua", "toru", "wha"]


{red="whero", green="kakariki", blue="kikorangi"}

And now ordered structs:

[firstName="Kiri", lastName="Te Kanawa"]

Sorted structs need to impart two different things:
  • the key/value pairs
  • the sorting mechanism

Within the sorting mechanism, there are some variations:
  • declaratively: sorting ascending, alphabetically, using a specific locale as the collation order
  • functionally: using a callback 

So how the hell to impart all that info in a literal?

There's been a bunch of suggestions (none of which I can share, sorry), but none have been complete or "natural-seeming". Abram floated some suggestions in a bug ticket - 4126544 - which are good suggestions, but not really solving the "literal" problem.

But I was discussing this tonight with my mate and ColdFusion testing machine Aaron Neff and we finally nailed a decent syntax I think (I await Sean to tell me otherwise ;-)

For the declarative approach:

sortedStruct = [key=value, key=value, struct]

Where the struct argument has the config details for the sort:

{direction="ASC|DESC", on="key|value", type="text|numeric", caseSensitive=boolean(false), locale="fr_FR"}

Put together as an example:

sortedStruct = [january=29, february=17, march=31, {type="numeric", on="value"}];

This would yield a struct that when iterated over would return the key/values in order Feb, Jan, March, as it's sorting on value (ascending is implicit given it'd be the default for that setting).

And for using a callback, instead of a struct one just gives the function:

sortedStruct = [key=value, key=value, function(element1, element2, struct)]


sortedStruct = [key=value, key=value, function(element1, element2, struct)

    var monthLengths = [january=31, february=28, march=31];
    return element1.value / monthLengths[element1.key] - element2.value / monthLengths[element2.key];

This sorts the struct on the proportionate daily value per month. Oh of course the comparator function returns one of <1, 0 or >1 as per all sorting comparator functions. I don't use the third argument to the callback in this example, but that's there to mirror other iteration callbacks which take a reference the whole collection as the last argument (should one need it).

I think that's a reasonable literal syntax for sorted structs, don't you? The only slight quirk is that there's the "special treatment" of the "last" item of the list of elements in the brackets, but I don't mind that. I suppose we could do this:

sortedStruct = [key=value, key=value](struct|callback)


But I think either syntax would be unambiguously parseable by ColdFusion, and I think it's clear what's going on when one eyeballs the code.

What do you think? Shall I float this as an idea?

Now... back to doing something that is a good use of my time [cracks another beer, starts Fallout 4].



Thursday 24 September 2015

Is the ColdFusion community about to lose the ability to update the docs?

(Hopefully this is a nod to Ian Betteridge in my subject line there).

I read this last night, on ticket 4010693:

Update: Adobe has copied the wiki docs over to AEM (Adobe Experience Manager). The AEM docs cannot be edited by anyone outside of Adobe. The wiki will be taken offline in about a week or so (guessing October 1st).

To verify, see Adobe's comments here:


And the comment in question is (from the pleasingly named "Jacob Jayakar Royal"):

Yes, Nitin, already migrated. All our CF content is there in helpx already. Wiki pages can't be viewed after a week or so.

So... um... what?

The only useful thing Adobe have ever done with the ColdFusion docs is to put them on the wiki so we (ie: the community) could actually fix them up. And now it seems they're taking it back in house?

I can't see anything that confirms Aaron's comment that "The AEM docs cannot be edited by anyone outside of Adobe", but that would really suck if it was so.

It would be really good if someone from Adobe (I'm looking at you, Anit) could clarify what's going on here?



Wednesday 23 September 2015

New bug status for ColdFusion bugs: DELETED/NEVERHAPPENED

This is just a repro of something Aaron said on the bugbase, which reveals a rather interesting act of weirdness on the part of the Adobe ColdFusion Team. And you know how I love those.

I spotted this today on the Adobe bug tracker (look quick, before it gets redacted!):

[ANeff] Bug for: Adobe is deleting thousands of tickets from their public bug tracker

Adobe is deleting thousands of tickets from their public bug tracker. 2,824 ColdFusion tickets have been deleted between June 9, 2015 and September 22, 2015.

Steps to Reproduce:
1) Try to view any of these ColdFusion tickets which were fixed in CF11 Update 3: 3041747, 3043855
2) Try to view any of these ColdFusion tickets which were fixed in CF11 Update 5: 3037144, 3039708, 3041684, 3041790, 3043111, 3043375, 3043657, 3044064, 3114274, 3226380, 3369472, 3520983, 3673298, 3842326
3) View attached 20150609_CFTicketsTotal.jpg and see total ColdFusion ticket count was 5,140 on June 9, 2015
4) View attached 20150922_CFTicketsTotal.jpg and see total ColdFusion ticket count was 2,316 on September 22, 2015
5) View attached 20150609_CFTicketsFiled.jpg and see -my- total ColdFusion ticket count was 455 on June 9, 2015
6) View attached 20150922_CFTicketsFiled.jpg and see -my- total ColdFusion ticket count was 328 on September 22, 2015

Action Items:
1) Restore the tickets deleted between June 9, 2015 and now.
2) Delete no more tickets.

My emphasis.

I can confirm a lot of the bugs I have raised have been deleted. I don't track the numbers, but I can see they're way down. Also looking at one of my older blog articles ("Most popular unhandled ColdFusion bugs"), all the ones I checked from that list - and a reminder: those are the most popular unhandled bugs: so ones we clearly care about - have been deleted.

So what's going on here then? What on earth would possess Adobe to delete this stuff? Even if a ticket has been fixed, it's all valuable historical information... not everyone will be patched-up or running the current version, and the ColdFusion Team has a nasty habit of closing tickets when they can't be arsed doing anything about it, so a lot of historical bugs will still actually be potentially impacting their clients. All this sort of action is achieving is increasing potential work for their clients as they troubleshoot issues which might actually already have been identified and discussed (if not fixed).

What's more, the content of those tickets is - on the whole - the community's work, not Adobe's. I put effort into tickets I raise so they're googleable and reproduceable and are intended to stay there so as to save people time if they run across the same issue. So please don't delete my bloody work, Adobe. Or Aaron's work. Or Ray's or anyone else's.

And, um... please explain.


And, indeed, they have explained. Apparently it was not their team that did it, it was another team. The team who looks after the Adobe bug tracker were a bit too zealous in making older versions of ColdFusion unselectable when raising new tickets, and in the process made all the tickets for those versions "invisible". Okey dokey then. I do have to wonder why no-one on the ColdFusion Team noticed this change, or checked the results of it, or... seemed to care, prior to Aaron bringing it up..?


Friday 11 September 2015

ColdFusion: getting the audit trail exposed on the bug tracker

Just quickly. Obviously I've fallen foul of the Adobe bug tracker in the last coupla days... mostly due to my dim wits, but not helped by the fact it doesn't present information as thoroughly as it could.

Aaron Neff has had the presence of mind to raise a ticket to get the audit trail exposed on the UI, which I think would help a lot with the clarify of what's going on, and also better expose the activity taking place on issues we're interested in.

The issue is "[ANeff] ER for: Display audit trail on tickets" (4054727). It's already been marked as "To Fix", but I'm sure we could get action on it more quickly if we got some more votes & observations added to it from as many people in the ColdFusion community as possible.

Can I urge you to go have a vote.



Sunday 11 January 2015

CFML: design brain-fart in Application-specific DSN definitions on ColdFusion

This article is just some analysis (and opinion, unsurprisingly) on the situation described in this bug ticket: "THIS.datasources changes ignored until CF restart".

In ColdFusion 11 (and Railo 4) one can specify data source definitions in Application.cfc, for example:

// Application.cfc
component { = "myApp";

    this.datasources = {
        myDsn    = {
            database    = "dbName",
            host        = "localhost",
            port        = "3306",
            driver        = "MySQL5",
            username    = "dbUser",
            password    = "dbPassword"
    this.datasource    = "myDsn";

(That's for ColdFusion 11. Railo's syntax differs slightly: there's an example of it further down).

Friday 28 November 2014

Local scope bug (or not, if you're the ColdFusion Team)

I just spotted this, and decided to look into it:

This defines a bugsituationbug in ColdFusion wherein if one deletes a local-scoped variable from a function, then assign an unscoped variable, that new variable goes back in the local scope, not in the variables scope.