Thursday, 30 July 2015

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

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;


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

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);

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.

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


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

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

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

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

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.

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.


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

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: