Thursday 30 July 2015

CFML: "Elvis" operator and null coalescing operators are two different things

G'day:
I've probably at least touched on this once before, but I'll do it again anyhow.

ColdFusion and Lucee (and before than Railo) have both got an operator ?: this is the binary equivalent of the ternary operator ?:. EG:

result = firstOperand ?: secondOperand; // binary
result = firstOperand ? secondOperand : thirdOperand; // ternary

The ternary version predates the binary one, so let's start with that. It works as follows:

result = booleanExpression ? valueToUseIfTrue : valueToUseIfFalse;

EG:

result = isInteger(17) ? "it's an integer" : "no it isn't"; // "it's an integer"
result = isInteger("nineteen") ? "it's an integer" : "no it isn't"; // "no it isn't"

The key thing is that the first operand needs to evaluate to a boolean. It's a shorthand for if/else.

Now I'm going to dip out of CFMLland for a moment, and back into the real world.

ColdFusion: can't tell its null from its... elbow

G'day:
Blimey: Acker is being of some use! He threw me this code last night, and asked what to make of it (well, OK, Sean asked me, but still).

found something unexpected:

a = isnull(request) && isnull(server) && isnull(form) && isnull(url) && isnull(33);

a = true ... meaning all are null
What the actual f*ck?

So I knocked together some test code to make things more clear:

// acker.cfm    
areAllNull = isnull(request) && isnull(server) && isnull(form) && isnull(url) && isNull({}) && isnull(33);

writeOutput("
isnull(request): #isnull(request)#<br>
isnull(server): #isnull(server)#<br>
isnull(form): #isnull(form)#<br>
isnull(url): #isnull(url)#<br>
isnull(33): #isnull(33)#<br>
isNull({}): #isNull({})#<br>
areAllNull: #areAllNull#<br>
");

And on ColdFusion, this yields:

isnull(request): YES
isnull(server): YES
isnull(form): YES
isnull(url): YES
isnull(33): YES
isNull({}): NO
areAllNull: NO


Adobe you dicks. How can an entire scope be null? How can 33 be null??? I looked in the docs ("IsNull()") and that didn't say anything like "oh, we just make sh!t up about what's null or not. To be honest we just don't know. I mean... how can one actually tell? What is null, anyhow?", which might explain it. But no.

Lucee are not lunatics:

isnull(request): false
isnull(server): false
isnull(form): false
isnull(url): false
isnull(33): false
isNull({}): false
areAllNull: false


I despair, Adobe. I really do. Chris Blackwell could not have put this better:


Raised as bug 4028246.

Update:

Just an update on this. In a moment reminiscent of the Orwellian position that 2+2=5, Adobe had this to say on the topic of the nullness of 33:


Are you having a f***ing laugh, mate?


And now these're something about Elvis to investigate too...

--
Adam

PHP 7: functions can now have type-checking on their return values

G'day:
This is a kind of "part 2" to the earlier article about type-checkinng on funnction arguments: "PHP 7: new feature: enhanced type-checking on function arguments". I was goig to roll both of these into one article, but decided I already had enough material for one article with what I already had about arguments, so I pressed "send".

In PHP 5.5 (which is where my career with PHP started, adn currently is... although I use 5.6 and 7.0 at home), the way PHP has implemented type checking on functions is a bit of a incomplete mess:
  • one can specify a type on an argument;
  • but only if it is a type of object;
  • ie: not an-inbuilt type like a string or an int;
  • and whilst one can specify a type on some arguments (as per above), one cannot specify a return-type for the function as a whole at all.

I dunno who decided that approach was a good one, but I just hope they can no longer make decisions regarding how stuff is implemented in PHP in future. I imagine it was a "design by committee" sort of exercise, and there was disagreement and no one position in the "organisation" was able to go "this is bloody stupid, we're just going to do it like this [goes on to describe a sensible way of going about things]".

But we are where we are.

So now functions can have return types. The general syntax for a function with type-checking utilised seems to be

[access modifier] [static modifier] functionName([[type] argumentName[=defaultValue]][,...])[ : return type] {
    // implementation
}


Wednesday 29 July 2015

ColdFusion: complete the implementation of associative array notation

G'day:
This'll be a quick one (not least of all because I only have about 20min to write it).

CFML has the ability to reference struct (and by extension object) keys either statically via dot notation, or dynamically via associative array notation, eg:

someObj = {
    someKey = someValue
}; 

value = someObj.someKey;

whichKey = "someKey";
value = someObj[whichKey];

This is cool, but it doesn't work when referencing functions, eg this does not work:

someObj = {
    someFunction = function(){
        // do some stuff
    }
}; 

result = someObj.someFunction(); // all good

whichFunction = "someFunction";
result = someObj[whichFunction](); // nuh-uh

This errors with:

Invalid CFML construct found on line 2 at column 13.

ColdFusion was looking at the following text:{

If associative array notation had been thoroughly implemented, this ought to work. However I suspect this latter situation did not occur to Adobe when doing the implementation.

PHP 7: new feature: enhanced type-checking on function arguments

G'day:
I'm back to doing some PHP beta testing. Or more "exploration" than testing, as I'm not being very rigorous about it. PHP 7 is tup to beta 2 now (download for Windows here: "PHP 7.0 (7.0.0beta2)"). Beta 1 came and went so quickly I never even installed it, let alone looked at it. I've had too ColdFusion 12 testing to do, and messing around with JavaScript. Even at work a the moment I'm pretty much doign JavaScript day-in/day-out at present. I've probably written 100 lines of PHP code (mostly unit tests) in the last few weeks.

But, anyway, the beta waits for no person, so I figured I should look at some more stuff.

PHP 7 has expanded its type-chekcing capabilities on function arguments. In "hilarious" very typical PHP language "design" fashion, PHP has had argument type-checking on object types for some time (I cannot be bothered looking up since when), but it's never had type checking on scalar values until now. I dunno what the thinking was there. I'm sure there's an oooh so good excuse for it somewhere, but I'm equally sure that would simply start draining IQ points if a person was to read it. I shall avoid as I've already got booze for draining my IQ.

Anyway, the good side of the situation is that they've added a bit of uniformity to the language here. Scalar arguments can be type-checked now too. Kinda. Let's look at that first, as it's an easy one.

Tuesday 28 July 2015

Adobe / ColdFusion: sh!thouse work ethic from CF Team members again

G'day:
Adobe have been really pretty good with patches for CF10 and 11 this year, they're released a number of patches, and I have no idea how many issues have been dealt with, but it seems like quite a few. Perhaps someone can dig the numbers up. And people like Anit and Elishia (admittedly: more Anit) do a good job at being responsive to client comms via Twitter, blogs, forums and now Slack.

However this hides a general attitude of lazy-arse-ness that infects the ColdFusion Team as an entity, and it's just not on.

The most recent episode of this is around this issue:

CFHTTP does not work with SNI enabled SSL (3598342)

Problem Description:
We are trying to connect via CFHTTP over SSL to a Windows 2012 IIS 8 server that has SSL installed and Server Name Indication (SNI) is enabled. http://en.wikipedia.org/wiki/Server_Name_Indication

Java 1.7 is supposed to work with SNI. ColdFusion's CFHTTP tag needs to be updated to handle SNI. SNI is an extension of the TLS protocol. Microsoft made this feature available in IIS 8 and as as more of these servers are setup ColdFusion will need to connect to them and will run into this issue.

ColdFusion 10 and ColdFusion 9 should be updated for the Server Name Indication (SNI) feature.

Steps to Reproduce:
Setup a Windows 2012 IIS 8 server and enable SNI for SSL. CFHTTP will not connect to it with SNI enabled.
This was raised in 2013. Note: this was back when ColdFusion 9 was still a supported ColdFusion version.

Last month (June 2015, one month shy of two years after the ticket was raised), Rupesh had this to say:
The SNI support has been added in ColdFusion 11. The change required for supporting this is quite big and therefore it can't be backported to ColdFusion 10.
Not f**in' good enough, sunshine. This issue was raised on ColdFusion 10, and it's impacting people using ColdFusion 10. You've had two years to get your sh!t together and conduct yourself like a professional team and get this issue sorted out on what's supposed to be a currently-supported version of ColdFusion. This means you need to fix broken sh!t.

You guys always seem to conveniently forget that your clients have paid for this software, and part of that - not-inconsequential - price tag is for the product to be supported for a number of years after purchase. In the case of ColdFusion 10, this is until June 2017. Another two years yet. We're already paid for you to fix this.

This attitude that the ColdFusion Team continues to let itself down with of variations of "we can't be arsed doing this" needs to stop. Treat yourselves and your paying clients with respect.

I invite my CFML-community readers to indicate any disapproval they might have with the ColdFusion Team in this regard by commenting on the ticket concerned, and on social media too. Once I put the Twitter message about this article out, I'll embed a link to it back here too.



Right. Back to watching telly.

--
Adam

PHP 7: PHP's error "handling" lunacy is getting on my tits

G'day:
FFS. I'm part way through an article on something completely unrelated, and needed to knock up some code to demonstrate PHP's "magic" __toString() method. That code worked fine, but my sample code cacked-out because bloody PHP still can't deal with unexpected error conditions coherently.

So here's something about __toString(), and something about PHP being f***in' stupid.

PHP's __toString() method is something one can put into a class so what if an object of that class is ever used as a string, then __toString() will be called, and if it returns a string, that string will be used. Fairly obvious stuff really. I wish CFML had this (I think Lucee kinda might? But ColdFusion does not). Anyhow, here's an example:

Saturday 25 July 2015

JavaScript: expectations re-adjusted re Promises

G'day:
First off a proactive apology. I generally sit in the pub on my Saturday afternoons in Galway (every second weekend), and write some ballocks on this blog. I think we're all used to that. I'm doing that now, but prior to kicking off with the writing I have already been sitting around for two hours watching the All Blacks play the Springboks in a hard-fought, narrow-margined 20-27 victory to NZ. And this entailed drinking four pints of Guinness as the build-up and match was under way, and I'm tucking into my fifth now. So f*** knows how coherent this article will be. The up-side is that I wrote the code for this beforehand :-S

OK, so the framing for this article is the previous article: "JavaScript: getting my brain around Promises", and my admission here is that I didn't actually get my brain entirely around JavaScript promises. I set my bar slightly too high (or: just wrong) for how I'd expect JavaScript to work, as it turns out. I'm spoilt by CFML, I guess. I'll update key points of that article, but make sure to read that one first as it's still mostly all right (IMO), and this article just clarifies a coupla points I didn't quite "get" last time.

My chief misapprehension was that JavaScript Promises themselves imparted some manner of asynchronicity to code execution, but this is not the case. They are just a handling mechanism for other code which itself is asynchronous. Once I wrote some code that respected that, things made more sense to me.

Here are some examples of how Promises help streamlining async code.

Friday 24 July 2015

JavaScript: (not ~) getting my brain around Promises

G'day:

Update / caveat

2015-07-24

I just had it wrong about this. See my next article: "JavaScript: expectations re-adjusted re Promises". Ignoring this side of things, the rest of this article does correctly reflect the mechanics of Promises, I think.

2021-01-14

I've just come back to this, and feel the previous update - originally buried halfway through the article - was not as emphatic as it should have been. My understanding / expectations of how Promises in Javascript work are just wrong in this article. I considered taking it down completely, but decided to leave it here. There's a lesson to be learned here: at the point at which things were not behaving how I'd expected, I should have done more research, rather than plouging ahead with even more wrongness. Oh well.

Thanks to Ryan for setting me straight in his comment.

My recommendation is to only read this if you want to laugh at me being extensively wrong. There is very little value in it other than that.

A few weeks ago I made a suggestion that some manner of Futures / Promises could be added to CFML ("What I'd like to see in ColdFusion 12 (redux, as is happens): Futures/Promises"). If nothing else this yielded a hilarious/frustrating series of comments. I also raised a ticket for same: 4010501.

I've messed around with a Future-ish sort of construct in the past ("CFML: Threads, callbacks, closure and a pub"), but never looked at Promises before, beyond reading the JavaScript docs for them ("Promise"), and being intrigued.

Way back when all the Acker-fracas was taking place I started knocking together some code to get me up to speed with JavaScript's implementation, just so I knew how they worked, and also to verify my suggestion had merit for CFML. I parked the code due to being sidetracked by other things, but I figured I'd write it up now. First I need to remind myself what all this code does.

According to the JavaScript docs, a Promise is:
The Promise object is used for deferred and asynchronous computations. A Promise represents an operation that hasn't completed yet, but is expected to in the future.

[...]

A Promise represents a proxy for a value not necessarily known when the promise is created. It allows you to associate handlers to an asynchronous action's eventual success value or failure reason. This lets asynchronous methods return values like synchronous methods: instead of the final value, the asynchronous method returns a promise of having a value at some point in the future.
I'm always rubbish at understand docs, so my reaction to that is "that's nice". I figured I needed to write some code and observe the behaviour, then I'd get a handle on what was going on.

The syntax of promise usage is:

new Promise(executor);
new Promise(function(resolve, reject) { ... });

Basically the constructor takes an argument that is a call back function, which itself takes two arguments (both call backs themselves), which can be called by the executor in either success or failure situations.

Wednesday 22 July 2015

ColdFusion CFML: weird shorthand operator restriction

G'day:
I dunno what to make of this one. This morning I was taking a look at an issue in the ColdFusion docs that someone on the #cfml Slack channel had raised, in that the docs said this;

Arithmetic operators

OperatorDescription
+= -= *= /= %=Compound assignment operators. The variable on the right is used as both an element in the expression and the result variable. Thus, the expression a += b is equivalent to a = a + b.
An expression can have only one compound assignment operator.

The thing that I had my attention drawn to is Adobe's inability to know left from right, so I've fixed that in the wiki version of the docs. I can't fix the ColdFusion 9 docs, but equally don't care about ColdFusion 9 anyhow.

However there's another interesting statement there:
An expression can have only one compound assignment operator.

What? Why?

I duly knocked together an example and ran it on ColdFusion  11:

// multiple.cfm

a = 17;
b = 19;
c = 23;

a += (b += c);

writeDump(variables);


Monday 20 July 2015

Are we getting closer to having a CLI & REPL on ColdFusion?

G'day:
I have to admit this is pretty much a click-baiting exercise, whilst also trying to drum up some community interest and support in a bugbase ticket.

A while back I raised 4013832, which says:

CLI/REPL - probably via CommandBox

I'm sure this has been raised before, but I cannot find the ticket.

ColdFusion needs a CLI/REPL for it to be taken seriously in these times. It's just a fundamental.

CommandBox is really good in this regard, so perhaps bundling it with ColdFusion under licence might be a solution.

This is by no means an original idea, and plenty of people have lamented the absence of this fundamental platform feature in ColdFusion for years. Indeed I've mentioned it a number of times previously on this very blog:
And I'd even raised a previous bE/R for it back in 2013: 3646258. The indication then was that it was going to be picked up for ColdFusion 11, btw.

I'm nothing if not predictably repetitive.

Saturday 18 July 2015

And... I'm back

G'day:
I'm pleased to say that Google seems to have got its act together, and this blog now seems to be showing up in Google's search results again, after an absence of a fortnight ("Gone from Google?").

I have no idea what happened, but I'd like to thank Andrew and Russell for looking into it for me (they know stuff about Google Webmaster Tools: I myself do not).

Righto.

--
Adam

Friday 17 July 2015

CFML suggestion: make queries implement an array interface

G'day:
This was not what I was gonna write about today, but it popped into my head as I was walking up upstairs to the office, so in a carpe diem moment, I'll do this one instead.

Queries are one of the most fundamental data structures in CFML; in fact perhaps the most fundamental data structure for CFML's original USP which was to pull data from a DB and get it into a web page. But if one thinks about it... it's one of the least functional. Beyond looping over 'em, there are a total of eight functions relating to them (from Query Functions). Four of those are all about building queries (queryNew(), queryAddColumn(), queryAddRow(), querySetCell()); two of them are for converting to another data type (valueList() and quotedValueList()); one to check of something is a query in the first place (isQuery()); and then there's one function for actually doing something with said query object: queryConvertForGrid(). And one basically should not be using that as it's only useful for using with <cfgrid>, and one should not be using that. Basically if one wants to manipulate a query object, on needs to fall back to QoQ, which is a bit of a rubbish way of going about things.

Thursday 16 July 2015

CFML: ColdFusion does some dodgy exception "handling"

G'day:
This was a curly one. I've been doing some testing recently, so I've been giving TestBox a bit of a thrashing. Yesterday I was a bit bemused that some of my tests were failing (that's not actually any sort of surprise given what I'm testing. Ahem), but other tests were erroring. yet they were testing much the same thing, and the condition causing the failure was the same for both the failing and erroring tests. I thought there was something weird afoot with TestBox, so I hit-up Luis about it.



I boiled the repro down to this:

// ErrorInsteadOfFail.cfc

component extends=testbox.system.basespec {

    function run(){
        describe("Replicating issue", function(){

            it("demonstrates a baseline", function(){
                expect(false).toBeTrue();
            });

            it("demonstrates the error", function(){
                var results = [1,2,3];
                results.each(function(result){
                    expect(false).toBeTrue();
                });
            });

        });
    }

}

This is really contrived, so don't pay too much attention to the code. Just focus on these two bits:

  • calling expect() directly in my test;
  • calling expect() within an iteration function, within an inline function expression.

The expectation on each is the same: that false is true. Which it isn't (I'm not going too fast, right? ;-), so the test should fail.

However I get this:


Notice how the second test isn't failing, it's actually erroring.

I raised a ticket for this: TESTBOX-127.

Luis came back to me a coupla hours later with the interesting observation that it seems when an exception is thrown within a closure, then ColdFusion doesn't just let it error, it wraps it up in a different exception, and throws that.

That's a bullshit thing for ColdFusion to be doing. Lucee, btw, does not do this: it behaves properly.

I expanded my tests out to cover a couple more things:

Tuesday 14 July 2015

CFML: should "Parameter validation error for the [functionanme] function" be a compile time error?

G'day:
I encountered this whilst trying to guess how a CFML function worked. When one passes the incorrect number of arguments to a built-in function, one gets a compile error, not a runtime exception. I'm wondering if this should be the case?

Sunday 12 July 2015

Gone from Google?

G'day:
Can you do me a quick favour? Google things like "adam cameron blog" and "cfml blog" etc... you know... things I used to rank in on Google? And report back with what you see (or as is the case: not seeing)?

It appears this blog has been blacklisted by Google for some reason. Or - being less conspiracy theorist about it  - suddenly there's been a complete reversal on my "SEO" (which I have to admit is something I don't actively pursue).

I'm in Ireland at the moment, so perhaps it's an issue with their Google, but I did notice I had my worst week for traffic last week for a coupla years.

TBH it's no great shakes from my perspective, but I do think some of the articles here are useful resources for people having CFML issues - and I've even helped a coupla people with PHP bits 'n' pieces - so it's a shame for it all to be unfindable now.

I notice Bing still lists the blog fine. But... who cares?

Odd.

Shrug.

--
Adam

Saturday 11 July 2015

CFML: Are collection iteration methods really significantly slower than looping statements?

G'day:
I've heard people say a coupla times that one should think twice before using CFML's new collection iteration methods (eg: .each(), .map() etc) should be treated with caution, because they are substantially slower than using looping statements (eg: a for() loop). Now I don't doubt that these iteration methods are doing more work that a loop statement, but I really was skeptical as to whether the difference really matters. I believe on should err towards writing the clearest code first, and worry about performance when it becomes something to worry about. And I not really think that the difference in performance here would be worth worry about, generally. And if there was a significant performance difference: it's more an indication that the language engineers have work to do, rather than simply dismissing a good coding tactic out of hand.

Friday 10 July 2015

ColdFusion 2016: Before I get all NDA-ed up

G'day:
This was a pleasing email to get:

Invitation to join the ColdFusion Raijin/Blizzard Prerelease Program!


Hello,
Because of your knowledge and interest in ColdFusion & ColdFusion Builder, you have been selected to participate in the Prerelease program of the next versions of ColdFusion codenamed 'Raijin' and ColdFusion Builder codenamed ‘Blizzard’. This program provides early access to the upcoming release.

500+

G'day:
This is yet another code-free article, I'm afraid. I know I've been slack recently :-( I do have a coupla code-centric articles in the pipeline, which should be out the door over the weekend, with luck.

Anyway, this is all about the #CFML Slack channel. Here's the good news:


That 500 (at time of writing... it should be higher than that by the time you read this) is the number of CFML community members signed up to the #CFML Slack channel. That's not bad given it's only existed for a coupla weeks. If you haven't signed up yet... get on over there. Just click the thing above to get invited.

Friday 3 July 2015

Critical Lucee Update (also attn Railo users)

G'day:
There's a security patch for Lucee released today, and if you're running Lucee 4.5, you really must apply it.

Update:

Actually don't do what I say here. LAS have ballsed-up and rolled this critical fix in with a bunch of other fixes, and as a result, I can't confidently say you should automatically apply this fix. The fix they're espousing needs to go through full regression testing on your system, rather than being a quick fix: I know of at least one upgrade that has failed because of this. I'm fucked off about having delivered this message and the having to back out of it, and I am following it up.


Lucee have released a blog article about it: "Lucee Stable Release - Security Update Included", and the executive summary is:

Today Lucee would like to announce the latest 4.5 stable release and point out that this release includes a very important security update, so we are recommending that you update to this release as soon as possible. We are however not releasing details of the security issue at this time for several reasons.

Wednesday 1 July 2015

20

G'day:
According to Adobe, ColdFusion is 20 today. I tried to track down the exact release date a while back but couldn't find an online press-release or the like, but Anit assures me it was 2 July 1995.

Hot

G'day:
So today is summer in London, and we're supposed to be hitting 33°C this afternoon, around about knock-off time.