Friday 30 May 2014

CFMX7 to CF11: how CFML has progressed

G'day:
In researching my previous article ("Hanging on to outdated knowledge: don't"), I had the displeasure of needing to write some code that would run on ColdFusionMX 7. It caused a lot of swearing, and a lot of "oh FFS, can you not even do that?", but it was cathartic in a way. CFML's really come a long way in between these two versions. And I don't mean pointless shite like <cfpod> and (yeah, I'm gonna...) <cfclient>, but just the language itself.

Here's a test file I knocked together, writing for ColdFusion 9's flavour of CFML. I know I said CF11 in the heading, but I was partially hamstrung by a requirement to have the code run on CF9. CF9 to CF10 is another thing (and then CF10 to 11 too; before one starts thinking about where Railo is taking the language).

Hanging on to outdated knowledge: don't

G'day:

Updated 2024-08-30

Reworded to avoid my misuse of the word "singleton" which I was using to mean "an object that is created once and reused", which is not a singleton. A singleton is about implementation, not usage. This was pointed out to me by John Whish of the CFML community, during a conversation we were having about misuse of that term. And in the spirit of not holding on to outdated knowledge: seems to be an appropriate update to make!

This has taken me a few weeks to sort out - I started on it well before CF.Objective() - but I think I've finally stared at log files for long enough to come up with my conclusion.

I'm working with a client's codebase. A lot of it was written a) a long time ago when come CFML coding practices were not as fleshed-out as they are now; b) initially on CFMX7 (which, of course, comes with penalties of its own). Their ColdFusion install has moved on to version 9, but some of their coding practices still languish in mid-last-decade.  Part of this is decision-makers arriving at a conclusion as to how ColdFusion does things based on how it did things in ColdFusionMX, and never re-assessing their position to see if it still had merit. Their position was never re-assessed partly because no-one ever questioned it. It was just the way things were done. Times and personnel have changed, so now questions are being asked. I hasten to add I don't think is at all unusual that this is the case, and often approaches stay static until someone new shows up and starts questioning stuff. We've had this @ work in the past, and I've noted it ("Hungarian Notation").

You might remember a while ago I had a look at one of CFML's favourite tropes: evaluate() is bad not least of all because it's slow ('"evalulate() is really slow". Is it now?'): that trope ends up being mostly bullshit. So one can't just settle in and accept what once might have been true will thereafter always be true.

The trope I'm looking at here is that on CFMX7 performance penalties in creating transient objects were such that they weren't a viable coding construct. The only feasible way of using object instances were as objects stored in the application scope and reused via ColdSpring during application start-up, and using those as services throughout the life of the application. Beans were an inviable notion, so they must not be used.

Object creation in older versions of CF certainly wasn't an efficient process, I agree with that.

Thursday 22 May 2014

London Railo Group: but wait... there's MoreBox

G'day:
Blimey... not one but two London Railo Group meetings next week. On Friday Pixl8 are hosting Luis, who's gonna be showing off CommandBox, which is a CLI for CFML. As well as that Alex (and/or Dom?) are going to be demoing the revitalised PresideCMS. Details here: "Luis Majano (New Coldbox and CommandBox) , Pixl8 PresideCMS Sneak Peak".

I have to concede I don't have content to manage, so CMSes aren't something that're on my radar, but Alex has shown me bits 'n' pieces of PresideCMS, and I am really really impressed with what he and Dom have done with it. It's a cliche, but it really seems like they've taken CMSes to the next level.

Luis showed me a bit of CommandBox at CF.Objective(), and it looks really bloody excellent. Definitely covering territory that the CFML platforms themselves should already be covering as far as package management and CLI goes.

I really wish I could be at this presentation too, but I'll be over in Ireland seeing my boy, and that's a lot more fun than CFML stuff. Sorry guys ;-)

But I urge you to sign up for this meeting as well (as the Railo one on Tues: "London Railo Group: Gert's over").

Righto.

--
Adam

London Railo Group: Gert's over

G'day:
A very quick news announcement. There's a London Railo Group meeting next Tues (May 27), at Pixl8. Gert from Railo is going to be there, and he will be doing his "Railo 5.0 and Beyond" presentation from CF.Objective().

CFML: Regex to the rescue again

G'day:
Once again (prev: "Regex for simplifying string manipulation logic") I found myself able to slough off a coupla dozen lines of code in a CFLib.org UDF, by using a regex (well: two) in place of a bunch of looping and branching logic.

There's nothing new in this article, but a good real-world demonstration of where regexes can replace logic.


This UDF (titleCaseList()) got on my radar because someone mentioned a bug it had today, and looking at the comments, there was an earlier bug still outstanding. So I decided to quickly fix it. Here's the code for the previous version:

Wednesday 21 May 2014

Quick & contrived & output=?

G'day:

Update:

The original wording of this was unnecessarily antagonistic towards one of my readers. I have reworded, and I apologise unreservedly for that.

A question came up the other day, regarding why one might specify the output setting on a CFScript-based function. All things being equal: this is seldom necessary, but the behaviour does change slightly if one explicitly sets it to false.

Monday 19 May 2014

Difference between Railo and ColdFusion regarding annotating CFCs

G'day:
Yeah, I'll write some stuff up about CF.Objective() shortly, but I need to plan that a bit more before I put pen to paper. This is a quick no-brainer (so playing to my strengths ;-).

Friday 16 May 2014

CF.Objective(): this is the end

G'day:
Sorry that I've not been writing much during CFO... I certainly intended to but wasn't in the position to, or the right mindset to do so. I've got lots of ideas queued up, but I need some time to do some research before I write anything down.

And remember when I said this:
Note to self: no hangovers. Do not put yourself in a situation in which you end up with a hangover.
Well that idea did not see fruition at all. This is part of why not a great deal of writing got done.

Anyway, what I did want to say is thank-you to the crew who organised the conference for us all: you really did a great job. And you know me... I'm not just saying that.

I'm not gonna list people's names - you know who you are anyhow - but it was really really excellent to catch up with a whole bunch of people I either hadn't seen since the last time we were @ the same conference at the same time, or who I'd only ever had dealings with online. If I meant to catch up with you and didn't... sorry!

OK, that's it. I have to go post a postcard to my boy, and then... [shudder]... back to the bar.

I never learn ;-)

--
Adam

Thursday 15 May 2014

ColdFusion 11.5?

G'day:
Rakshith did a good job in the latter half of the main Adobe ColdFusion 11 presentation @ CF.Objective() yesterday. The first half was still a bit of a sell job on <cfclient>, but in the latter half Rakshith rolled up his sleeves and showed us some code. Which is what developers at developer conferences want to see. Towards the end of the presentation he (or was it back to Elishia at this point?) spoke about some of the stuff they're looking at for ColdFusion 2016. I sent out Twitter messages about it all at the time, but here it is again.

Regarding regex: two things I'd like everyone to do

G'day:
Today my mate / colleague Duncan Cumming is my muse. But - sorry Daddy Duncky - not in a good way.

There was a question on StackOverflow over night "Need regular expression to insert a numeric value between filename and extension?". Dunc's given a reasonable answer, but also perpetuated an old trope which seriously needs to be put to rest:
Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems.
Thanks for that, Jamie Zawinski. And also thanks to Peter Boughton for giving Duncan a smack down on this. Peter is probably the chief CFML-community regular expression guru I know. Yes: more so than Ben Nadel.

The thing is... using regexes isn't that hard. Obviously one can do some incredibly complicated and impenetrable with them, but this is the same as with any technology. But I think stupid (if slightly amusing, granted) quotes like the above have gone a long way to making regular expressions seem mystical and complex to people. It's not. It's just pattern matching. They're no where near as complex as the CFML programming logic we work with every day.

Wednesday 14 May 2014

CF.Objective(): what to put into ColdFusion 2016

G'day:
First things first... I'm suffering from "writer's block" (such as it can be described with what I do here), which is really unfortunate whilst sitting at CF.Objective() and having no idea what or how to write. This frickin' hangover doesn't help, either.

Anyway, I'm only slightly engaged with the keynote presentation (sorry Jen), so will dwell on something Jason Dean said in the intro whilst I direct one ear to the front of the room. Adobe are running a competition today wherein they are soliciting the community for what people consider the top five (I think it was five?) potential features for ColdFusion 2016. So this article has a twofold purpose... for me to formalise my thoughts whilst I write, and for you lot to put your oar in. The competition only runs until after lunchtime today (so like 4h time), but in general let's think about this.

I've previously written down my thoughts on this back before ColdFusion 11 was released: "What do I want to see in ColdFusion 11?". It's pleasing to see a lot of that list have actually made it into the product:

  • Member functions
  • First class functions
  • 100% CFScript coverage
  • queryExecute()
  • Express install

Monday 12 May 2014

ColdFusion Builder 3.0 installation fail..?

G'day:
Twitter won't let me send this image for some reason, so I'll post it here.

I'm trying to install ColdFusion Builder 3.0 on my Win 8.1 (64-bit) laptop. I've just D/Led the current (Kepler) Eclipse 4.3.2 64-bit installation, and that runs fine.

Having tried to install CFB as a plug-in to that, it installs fine and says "yeah good" at the end, but when it then goes to start Eclipse, I get this error:


Anyone know what gives?

I googled about, and there's not much about this, but generally it's people using a 32-bit JVM when they should be using a 64-bit one. Eclipse itself picks up my JAVA_HOME value fine, which points to a 64-bit JVM. So I don't think that's it.

I really don't want to waste any more time than is really necessary on this as all I'm installing CFB for is in prep for Simon's <cfclient> prezzo @ CF.Objective(). I thought I might actually do a "G'day World" exercise with it first. But I have no interest in CFB beyond that.

Anyone encountered this, and know what the story is? I'd google more thoroughly, but I'm on a shonky free wifi connection @ LHR, and have a bunch of more important things to do.

Am just hoping someone's had this and knows what the story is. Do not do any special investigation for me if you don't automatically know. I can look it up later on when I have a better connection and more time, if push comes to shove.

Cheers all.

--
Adam

Saturday 10 May 2014

CF.Objective(): what I will/might go see

G'day:
Bloody hell... this is proving to be a bit of a mission. There are so many good presentations and presentations I feel I should go to and a lot of overlap & different twists on similar content. What I do know is my brain is going to be busy. Note to self: no hangovers. Do not put yourself in a situation in which you end up with a hangover (there, that's out of the way, I can ignore that idea now).

Well that was unexpected

G'day:
Well... once again I am gobsmacked by the community, and in a good way.

Friday 9 May 2014

Reflection

G'day:
No I'm not being philosophically introspective; I mean the Java kind of reflection. Recently there's been some yipyap about the place regarding both Railo (RAILO-3001) and ColdFusion (3753710) steamrolling over perfectly good Java object methods with member functions of their own which work differently (and less well than their Java counterparts). Both these happenstances have broken FW/1, and have made Sean grumpy. Yikes.

But I don't care about that for the purposes of this article (no diss', Sean: I think you've got it covered anyhow ;-).

Thursday 8 May 2014

CFML: Advice for Adobe re Railo

G'day:
I was a bit surprised to read this this morning:

The sole reason for adding this functionality was to make it easy for the frameworks to define the datasources from within the framework without going through the administrator. If one has to go through the administrator to get the encrypted password, that defeats the whole purpose. You can very well keep it defined there. So why define it in the application at all? 
As far as the railo approach is concerned, I don't know the details of their implementation. As Hima said, after putting the encrypted string, your code would not be portable because encryption will be installation specific. In case they are claiming the encrypted string is portable, it would mean that they are encrypting it with a static key same across all installation which is not at all a secure practice.

I dunno if Rupesh was meaning "in general" or just "in the context of this topic".

However, to be clear, the very first thing Adobe engineers - especially senior ones who seem to make decisions - should be familiar with is how Railo does stuff, and what features it has. In the context of this specific issue, as soon as I compared ColdFusion's functionality unfavourably with Railo's equivalent functionality, Rupesh should have spun-up his Railo instance and had a look. That's if he didn't already know about it.

As Adobe was playing catch-up with this feature, all the devs involved in it should have already gone over the feature in Railo and used that as a basis to make the CF implementation at least as good, if not better.

I'd be fine if Rupesh had said "yeah, we looked at that and didn't think it had merit because [reason here]", but it sounds like he didn't even know about it.

It would not surprise me if Rupesh doesn't even have Railo installed.

Adobe have to be all over what Railo is doing. They should be members on their mailing list (not just lurking, but actively discussing stuff), they should be checking out all the new features (and bugs!) as soon as they come in, and in general know exactly what the opposition is doing. Not least of all because they could learn a thing or two from Railo's implementation of things.

Obviously it cuts both ways, but I already know the Railo bods are fairly familiar with how ColdFusion operates.

When I read stuff like this, the silo of naïveté that the Adobe team resides in that I have a mental image of gets slightly higher, and the walls slightly thicker.

--
Adam

Wednesday 7 May 2014

CFML: We learn something every day...

G'day:
This was brought to my attention via one of my colleagues. I guess it's predictable behaviour, but it's less than ideal, I think.

Here's some code:

// Parent.cfc
component {

    function f(){}

}

// Child.cfc
component extends="Parent" {
    include "mixins.cfm";
}

<cfscript>
// mixins.cfm
function f(){}
</cfscript>

<cfscript>
// test.cfm
o = new Child();
writeDump(o);
</cfscript>

So here we have Parent.cfc which implements a method, f(). Child.cfc overrides this method, but uses a mixin include to do so. In our case it was because we need to override the same methods in a coupla places, hence factoring the f() method out into an include we can share between CFCs.

And on ColdFusion, we get this:

For the record: Cameron vs <cfclient>

G'day:
This is just cos I need some typing space.

Isaac Sunkes posted on another article:
If you try to google anything CF11 or CFCLIENT or similar looking for some useful information to help you learn new features, search results are sometimes just Mr G'day's post complaining about them.
How is that useful?
Isaac... let's google. I've googled for "cfclient". This is with an incognito window, as Chrome remembers what I tend to look at, and obviously I have been busying myself with <cfclient> recently.

Tuesday 6 May 2014

SotR14: my schedule

G'day:
A while ago I did an article on what I would like to go see, based on the likely sessions, but giving no thought to the schedule (which was not out at the time): Scotch on the Rocks: which sessions am I going to? (2014 version).

Now the schedule is up, so I'm able to revisit my initial thoughts and formulate a plan of attack.

CFML: Adobe agree to revise their stand on prefixing of list-oriented member functions

G'day:
Just very quickly... you know I wrote an article the other day, "ColdFusion 11: if Adobe haven't quite sapped yer will to live yet..."? Well we got some input from community members other than just myself, and the resounding feedback was "prefix the list member functons with list".

And Rupesh posted this response today:
all right. marking it as ToFix and we will include it in the first update.
In case one has used these list methods, he/she would need to change the code.
Nice one. I guess that's two beers I owe Rupesh now. Cheers fella.

And... go the community input! See it does help if you let Adobe know what you think, rather than just sit there silently gritting yer teeth. So if you find a bug: raise it. If you think it's worth people knowing about, or if you need support making your case: let us know so we can pitch in too.

Anyway, cheers everyone involved in this: good work.

--
Adam

Monday 5 May 2014

Looping in CFML: community input solicited

G'day:
Yesterday I wrote-up my experiences with the new cfloop() construct in ColdFusion 11: "ColdFusion 11: cfloop in CFScript very broken". The same construct exists in Railo, btw (it's nowhere near as broken).

I raised a ticket with Adobe summarising my findings: 3754577. Overnight Rupesh has come back to me, with this comment:

Though we have added a generic approach for the script syntax for all tags, it does not work in cfloop's case as the tag implementation is directly in the generated code. the exception being query or file and that is why looping over a query or file works but others don't.
Though it would be ideal to do this for completeness, is this really required? We already have cfloop equivalent in cfscript - using "for", "for-in" and "while" loops. file is the only thing that is not supported by "for" or "for-in". I feel we should stick to the "for", "for-in" & "while" and throw a good error for cfloop with indexed, array, list, collection and condition. Thoughts?

It's great to get decent, thoughtful, feedback. I put my own thoughts down in response:

I'm split on this on.

On one hand if you're gonna do this porting of tags to CFScript with this generic approach rather than with a situation-specific one, then I think the approach should be all-encompassing. If it's generic don't second-guess stuff, just do it.

On the other hand, I think perhaps having implemented cfloop() at all was perhaps a bad move. Instead it would have been better to augment the existing CFScript looping construct: for(). There's no reason why that could not have accommodated query- and file-looping functionality. The benefit of this is that for() is a familiar construct for everyone, and it doesn't necessitate yet another looping construct.

What you've ended up with is - same as with the list member functions - a situation where the language isn't "hackable". One cannot simply infer how the looping works from the behaviour of existing constructs. There is no rhyme or reason why one would use for() for arrays, but cfloop() for queries. It makes no sense. One needs to know the inner workings of what the CF Team decided to know how things work, which I think is fairly opaque language design.
I am going to solicit more community input on this, to see what people think.
I decided not to add it to my comment on the bug tracker, but I'll add it here. I also think too often the Adobe team opt for "what's quickest/easiest" rather than "what's best". And I really think this needs to stop. The language needs to come first, then how much effort is involved comes secondary to that. It would be better to not do it at all, rather than to an incomplete job due to timesaving.

A case in point is this looping thing. In CFScript we now have:

  • for() - indexed, array, collection
  • while() / do() - conditional
  • cfloop() - files, queries
  • listEach() - lists
  • type-specific iteration functions
(I separate those last two out as there's no "procedural" way of looping over a list in CFScript, I think; one needs to use the functional way).

Adding in yet another way of doing looping just to cover files and queries seems wrong to me. They should have either just added in the appropriate iteration functions, or added functionality to for() to handle it. Or both. Both would have been the better solution. But cfloop() is just PHPifying to me.

But, anyway, it's not all down to just what I think (and I wouldn't even want that to be the case). I was hoping you people could pitch in on the conversation too. Care to add your comments onto that ticket I linked to above?

Cheers.

--
Adam

Sunday 4 May 2014

ColdFusion 11: Adobe goes some way to correctly identifying what constitutes an integer

G'day:
This is a follow-up to all the shenangians around isValid() and integers and what not: "Can we please agree that Adobe is not the arbitor of what constitutes an integer?". Adobe have done some work to improve things here.

ColdFusion 11: cfloop in CFScript very broken

G'day:
I started having a further look at what Adobe have done for CFScript in ColdFusion 11. According to their docs ("CFScript: Script support for tags") "ColdFusion 11 allows you to write all the tags in the script format in a very generic manner". A colleague of mine was looking at how <cfloop> was implemented in CFScript (yeah... why? I dunno... they shoulda just used for() loops), and we quickly came away going "shit, what a mess".

Defining datasources in Application.cfc

G'day:
This feature of both Railo and now ColdFusion hasn't been talked about as much as I think it should have been. Both CFML platforms - as of 4.1 in the case of Railo, and 11 in the case of ColdFusion - allow one to define entire datasources in Application.cfc. Not simple reference to existing DSNs created in CFAdmin (or via the Admin API, if you've ever tried that), but defining the whole thing right there in Application.cfc.

Saturday 3 May 2014

ColdFusion 11: what <cfclient> compiles down to

G'day:
One of Sean's comments on another article ("ColdFusion 11: <cfclient>... how does normal CFML code and <cfclient> code interact?") got me thinking:

This doesn't surprise me at all: cfclient generates JS that runs in the browser; outside cfclient, you have regular CFML that runs on the server. You can't expect them to know about each other. This is like the frequent RTFM questions on SO about using CFML variables in JS!


Whilst I don't think it's quite so painfully obvious as Sean would like us to think, he does raise a reasonably good point. I'll reproduce my response too (which is a reasonable prelude to this article):

I suppose it depends how the JS is generated. Is it extracted from the file at compile time and created? Or is it compiled in situ as part of the compiled class, then at runtime JS is generated from it and returned to the browser? I'll need to check that (I suspect it's done at runtime).

If it's done at compile time, then, yeah... there's no way initialising any variables referenced in the "server side" part of the source code which are also needed in the client side part of it, as the values won't be known.

If it's done at runtime, it should be easy enough though? Same as how one might do it with CFML writing out a <script> tag, containing JS variables which have CFML variable values as their values?

If it's all done at compile time, I don't see why <cfclient> is a *tag* as opposed to a different file type (.cfjs or something), as there's no merit in having both server-side (outwith the <cfclient> tags) and client side (within them) in the same file. Because never the twain shall meet, as you point out.

Looks like I have another blog article to write on the topic...

List of articles on Adobe ColdFusion Forums for Anit

G'day:
This is not an article, per-se, but just a list of links for Anit, I'll then be posting the link to this on Twitter. The links below are simply reproductions of my existing blog articles on the given topics, and do not represent new writing on my part.

Anit, these are the questions I wanted to ask the Adobe ColdFusion Team about some features of ColdFusion 11. As you suggested, I have posted them on the Adobe ColdFusion Forums. Here are links to the forum articles.



Thanks mate.

--
Adam

ColdFusion: Credit where it's due: cheers Rupesh

G'day:
I'm pretty hard on Rupesh at times (where those times are "most of them"), but I've just being doing some back-and-forth with him on the bug tracker regarding some bugs / enhancements I'd raised in the past. And it's all been pretty positive.

I'd raised one about first-class functions a week or so ago (so way too late for anything to be done about it in ColdFusion 11): "Built-in functions as "first class" glitch in function expressions", and he's been investigating what's up, and gave me some more repro information; and I've updated with a better repro case as I was wrong about what I thought the issue was before.

Quite a while back I asked for <cfloop> to be deprecated (yes, really; but only in a certain regard): "Deprecate CFLOOP/array and try again", and I never expected any movement on that, but he's suggested a good resolution which doesn't require any deprecation nor would it cause any backwards compat issues.

When I was looking at other languages, a while ago (RubyPHP), I had a look at what other interesting operators these and other languages had, and suggested <=> for CFML: "<=>: compare operator"; they might take this up in the next release.

And I had previously suggested combining all the array-finding functions into a single function, and deprecating the existing ones: "arraySearch()". he's been giving that some thought too; basically agreeing, but being uncertain about my suggestion of deprecating the existing ones.

A few other ones I've raising in the past have simply been marked "to fix" without any further commentary:



Not only am I pleased here because the feedback has gone the way I wanted it to; I'm just pleased there's feedback and a sense of consideration going on here at all. I'm completely OK with any bug / enhancement request I raise being rejected provided there's sounds, transparent reasoning behind it (I don't even need to agree with it; I get that opinions differ)... it's the sense of collaboration and inclusiveness that's important. Of course it's even better still when the ticket gets marked "to fix".

Thanks for the good work Rupesh. Rakshith: buy that man a beer.

--
Adam

Thursday 1 May 2014

ColdFusion 11: allowedextforinclude functionality has changed. But the docs haven't been

G'day:
Remember this one: "ColdFusion 11: preventing files from being included? WTF, Adobe?". I can confirm this verymoderatelyslightly contentious feature has been changed in ColdFusion 11, but the docs have not been updated to reflect the change.

(Note: this functionality was changed to compileextforinclude, by the time ColdFusion 11 was actually released).

The issue is summarised thus (from the article linked-to above):

[...]out of the box ColdFusion 11 will only allow the inclusion of CFML and HTML files. Why? They cite "for security reasons". Here's a quote (posted in the bugtracker, originally from the pre-release forums):
"Vamseekrishna Manneboina: Yes, this was done as part of a security measure. You can now only include CFM/CFML files by default. You can specify additional extensions via a property called allowedextforinclude in neo-runtime.xml. By default, HTM and HTML file extensions are already added to this list/property, thereby allowing for inclusion of HTM and HTML files too by default."
OK, I disagree there's merit in this, some others agree, others disagree. But... so be it. I actually thought - if I was in a charitable mood - that the people that were "for" this change made a reasonable case for its inclusion, so - whilst not agreeing with them - I was content to just shrug and go "yeah, oh well".