Showing posts with label ColdFusion 11. Show all posts
Showing posts with label ColdFusion 11. Show all posts

Friday 28 February 2014

ColdFusion 11: <cfhtmltopdf> is pretty good!

G'day:
I had a bit of a false start with getting cfhtmltopdf() working (see article "ColdFusion 11: cfhtmltopdf() a non-starter. Literally"), but that turned out to be an installer problem, rather than anything wrong with the functionality itself. Once I got it going, I gotta say I'm pretty impressed.

ColdFusion 11: undocumented new feature regarding <cfprocessingdirective>

G'day:
I can't see this documented anywhere, other than as a passing comment in the bug tracker, so I figured I'd mention it here.

ColdFusion 11: Adobe listening to their clients

G'day (from London again now):
Earlier in the week I wrote an article "ColdFusion 11: lists and arrays and empty elements and weird ways to fix stuff", which commented on some poor logic / common sense behind the way Adobe had chosen to fix an issue around how the application setting this.sameFormFieldsAsArray works, in that the array it creates ignores empty form values.

Tuesday 25 February 2014

ColdFusion 11: <cfhtmltopdf> a non-starter. Literally

Update

This sorted itself out after two de-/re-installs. None of which showed any errors, but only the last one installed the PDF stuff. Unimpressed.

G'day:
This might be me doing something wrong, or a known issue or something, but I can't get <cfhtmltopdf> to work. Which is annoying because for once in my CF career... I actually need to generate some PDFs. Today. Right now.

ColdFusion 11: .map() and .reduce()

G'day:
More ColdFusion 11 testing. This time I look at the new .map() and .reduce() methods that each of array, struct and lists now have. It's mostly good news.

ColdFusion 11: lists and arrays and empty elements and weird ways to fix stuff

G'day:
Someone has asked me to draw attention to this issue (3560964), as they are dissatisfied with the way Adobe have handled it. Personally, I'm ambivalent, but err more towards the community members' positions than Adobe's. The detail of the ticket boils down to this:

Prior to CF10 to turn a repeated form element into an array we used getPageContext().getRequest().getParameterMap().

This worked smoothly this feature was replaced in CF10 with the application flag:
<cfset This.sameFormFieldsAsArray = true> This works nice except it removes empty elements. getPageContext()...getParamterMap() now returns an empty struct.

ColdFusion 11: query column types preserved when serialising to JSON, eh?

G'day:
I'm playing catch-up with the comments on the blog, and one of said comments from Roberto Marzialetti got me looking at an old article: "ColdFusion vs JSON. How to make a developer cry". In this article I mooted an alteration to how ColdFusion serialises query data so as to preserve the column types. This is critical with queries because CFML operations on this data such as QoQ is type-sensitive. So we need the data type.

Monday 24 February 2014

Breaking out of an each() loop

G'day:
I'm just soliciting opinions here. I'll raise a ticket for it anyhow, but let's see what people think.

ColdFusion 11: a lot of string member functions have not been implemented

G'day:
I was writing some scratch code today to parse some strings, and I tried to do this:

matches = myString.reMatch(regex);

And this didn't work. For some reason, Adobe have not implemented it.

So I've just been through all the functions that act on strings, and checked whether Adobe have bothered to implement member functions for them.

Sunday 23 February 2014

ColdFusion 11: preserveCaseForStructKey

G'day:
There's a new feature in ColdFusion 11:

Case preservation of struct keys

Currently, the cases for struct keys are not preserved in ColdFusion. The struct keys get converted to upper case automatically.
[...]
To enable case preservation of struct keys at the application level, modify the application.cfc file by setting:
this.serialization.preservecaseforstructkey = true

On a whim, I decided to check how well this had been implemented...

ColdFusion 11: member functions implementations and suggestions

G'day:
Enough of the rhetoric, here's some code. I'm having a look at the new member functions in ColdFusion 11 today. And have some samples, observations and suggestions.

Saturday 22 February 2014

ColdFusion: Fixing any bug has backwards compatibility concerns

G'day:
I'm going to bang on about isValid() and integers some more. You've been warned.

Right, so I was horrified to see that this is the case in ColdFusion:

isValid("integer", "$,1,2,$,2352345,$"): YES

And, what's more, having used ColdFusion to establish that $,1,2,$,2352345,$ is in fact an integer, if I then try to use it as an integer, ColdFusion breaks. At least it gets this half right. I discuss this at undue length in "Can we please agree that Adobe is not the arbitor of what constitutes an integer?".

Good old Rupesh poked his head above the parapet briefly, and offered a better response than one might expect here:

Avatar




There is no doubt that this behavior is incorrect. It is obviously wrong and it should be corrected. However, it has been like this forever and making such a fundamental change has a great potential to break a lot of applications. We dont want to do that in this release. As Rakshith has already communicated, we plan to take up such changes in 'Dazzle' where we will correct the behavior without worrying about backward compatibility.

This is an improvement over his earlier comment on the topic:

  • Rupesh Kumar
    2:53:06 AM GMT+00:00 Apr 24, 2012
    This has always been the behavior and changing this would result in backward compatibility issue. It will not be fixed.

There's a fundamental error in Rupesh's internal logic here. To suggest that fixing a bug somehow has backwards compatibility issues is utterly specious.

Intrinsically "a bug" causes some manner of behaviour to occur. It's a bug because the behaviour is incorrect. And, intrinsically, if a bug is fixed, it is implicit that the previous behaviour will change. That's the entire reason for fixing the bug: to replace incorrect behaviour with correct behaviour. So, on the face of it (and this is why I say his position is specious, not simply out and out frickin' stupid... although it is also that), this creates a backwards compatibility consideration. Because the new (correct) behaviour will be different from old (incorrect) behaviour.

But this is the nature of fixing bugs. The behaviour of the buggy functionality changes because it becomes "not buggy". If we were to clamour "backwards compatibility!" each time we considered fixing a bug... no bugs could ever possibly be fixed. And clearly we do fix bugs (obviously). So "backwards compatibility" is not grounds for not fixing bugs. Because it is not actually a valid consideration.

CFML: Feature toggling for both Railo(/Lucee) and ColdFusion

G'day:
I'm just drawing attention to part of the bottom line of my previous article ("Expressions and operators and doing weird shit"), as I think it's a significant feature request for both Railo and ColdFusion.

I've suggested both Railo (RAILO-2926) and ColdFusion (3712059) should implement a feature toggling system. This would resolve issues both platforms have with cross-compatibility and backwards-compatibility.

There are a few things recently that I've raised with both companies and the response has been "be that as it may... we can't do it due to backwards compat" (to be fair to Railo they are far less emphatic about this, and usually consider how else to approach things; in Adobe's case it's just their favourite mantra when they don't feel like fixing something, I think).

The degree of validity of the compatibility issues is one thing, but it is a real consideration. However I want Adobe to stop wallowing in the past, and I want Railo to not have to wallow alongside them for the sake of cross-compatibility. Plus there's some own-goal issues with some Railo code too.

What I think both need is a feature toggling system which can be applied to a feature meaning that by default a new backwards-incompat fix will work for everyone for whom there isn't a backwards compat issue (which, let's face it, will generally be most people, for any given issue). However to preserve the sanity of people whose code is impacted by these fixes and just toggle them off until they get around to updating their code to not rely on broken CFML behaviour.

I'm so fed up with some of the inertia we're seeing in CFML that something needs to be done. And especially for ColdFusion... now's the time, given we're in the dev phase of ColdFusion 11.

As always... thoughts / comments?

I think I need to do one more gripe about integers, but then I can crack on with looking at new stuff in ColdFusion 11. I'm still finding good stuff! :-)

--
Adam

Friday 21 February 2014

ColdFusion 11: queryExecute()

G'day:
No ifs or buts this time... Adobe dun good with a new feature in ColdFusion 11: queryExecute().

Thursday 20 February 2014

ColdFusion 11: good stuff

G'day (again!):
But it's not all bad. Some of the things I've looked at so far have worked well.

Member functions

Once I got TestBox working (see "ColdFusion 11: first bug. Bad bug."), I was able to run those unit tests I wrote yesterday ("TestBox, BDD-style tests, Railo member functions and bugs therein"). I'm pleased to say that ColdFusion 11's member function implementations for struct functions are pretty good. Here's the results (just the issues, not the successes):
  • +new() tests (9 ms)


    • has not been implemented (8 ms) - The incoming function threw exception [Object] [The new method was not found.] [Either there are no methods with the specified method name and argument types or the new method is overloaded with argument types that ColdFusion cannot decipher reliably. ColdFusion found 0 methods that match the provided arguments. If this is a Java object and you verified that the method exists, use the javacast function to reduce ambiguity.] different than expected params type=[expression], regex=[.*]
That's OK. That test was in there for completeness only. It makes no sense to call a .new() method on an existing struct. Maybe as a static method on the Struct class, but we don't have those, so fair enough.
.find() here works exactly the same as structFind(), which is a bug... but an existing bug (3710341). However it should be fixed, and now is the time to do it.

Adobe have not implemented the .get() method. This is no great loss, but for the sake of completeness should be there (3710345).

They've also not implemented the .filter() method, which is a bit of an oversight! Raised as 3710336.

And structKeyTranslate() is a Railo-only function, and one of dubious merit, so it's right the tests fail there.

Now it looks like I'm just raising more bugs here (and, well, I am), but bear in mind that the tests for all the other methods worked perfectly, and cross-compatible with Railo. Adobe have done a good job here.

They've done member functions for the following data types:
This is better coverage than Railo has. Good work. I've not tested 'em all yet, but I will do.

First-class functions

Built-in CFML functions are now "first class" and can be treated as values. Here's a silly example:

//firstClass.cfm
stringModifier = function(s, f){
    return f(s);
};

s = "G'day World";
writeDump([
    stringModifier(s, ucase),
    stringModifier(s, reverse),
    stringModifier(s, len)
]);

This outputs:

array
1G'DAY WORLD
2dlroW yad'G
311

Not the most handy thing ever, but as an architectural thing, it makes CFML seem that little bit more "grown-up".

Null-coalescing operator



Update 2020-09-09

For the sake of full disclosure, my position has now changed on this. My initial position (as per below) was based on my poor understanding of other language's implementations of the "elvis operator".

IMO the ?: operators should expect a boolean value as the first operand, not potentially a null. Null in CFML is not considered a falsey value, and is invalid for use in a situation requiring a boolean. The short-circuit ?: operator should work exactly the same as the long-hand ternary operator, other than one can omit the "if true" value, where the result of the expression is simply the first operand if it's true or truthy.

If CFML was to be implementing a null-coalescing operator - something different from the short-circuit ternary - it should perhaps have better used ??.

However the horse has bolted, and I will concede I was an initial voice in encouraging this particular misstep on Adobe's part.

This is playing catch-up with Railo a bit. The null-coalescing operator is a binary operator that works thus:

result = firstValue ?: secondValue

The rule being that the result will be the firstValue if it is not null, otherwise it will be the second value. Simple. Both Railo and now ColdFusion have messed it up a bit though, confusing the concepts of "null" with "not defined".

This demonstrates the correct operation of the null-coalescing operator:

//nullCoalescingOperatorCorrect.cfm
nullVariable = javaCast("null", "");
variableToSet = nullVariable ?: "default value";

writeDump({variableToSet=variableToSet});

This outputs:

struct
VARIABLETOSETdefault value

because nullVariable is null, it's not used for the value of variableToSet; "default value" is instead.

However this demonstrates where CFML goes a bit wrong:

// nullCoalescing.cfm
variableToSet = notDefined.invalidProperty ?: "default value";

writeDump({variableToSet=variableToSet});

This should error. Because notDefined isn't null, it's not defined. And something that isn't defined cannot have a property (. operator), so notDefined.invalidProperty is just an error situation. However this "works" in CFML:

struct
VARIABLETOSETdefault value

I raised this yesterday with Railo: "Probable bug in null-coalescing operator", and Igal and I just got the hump with each other, but Gert is erring towards "right or wrong, I'd prefer 'wrong'". I'd prefer "right". The way to solve it so that everyone is happy would be to additionally implement the safe navigation operator, as I mention in an earlier article: "Thinking about operators in CFML". This way we have the ?. operator acting how it's supposed to, and the ?: acting how it's supposed to. Not implementing ?: so that it alters how the . operator works.

I'm gonna raise a bug (3710381) & and E/R (3614459) here.

But having the null-coalescing operator is a good 'un.


I'm gonna press "send" on this now... I've got some other stuff to look at and my eyeballs are gonna fall out of their sockets if I stare at this computer for too much longer (I've been at it for seven hours non-stop so far today, and it's still only 2pm).

--
Adam

Wednesday 19 February 2014

ColdFusion 11: preventing files from being included? WTF, Adobe?

G'day:
This is a follow-on from my earlier article "ColdFusion 11: first bug. Bad bug.". I'm writing it up separately here as it's a slightly different issue, worth discussion.

That previous issue cropped up because I was trying to run my TestBox regression tests on ColdFusion 11, and somewhere under the hood TestBox includes (via <cfinclude>) some JS and CSS files. This is not an uncommon practice (more common with JS than CSS, that said), and a handy way of writing out JS at request time. This is necessary sometimes to "pass" server-homed data to JS code, before running the rest of the JS out of .js files, executed on the browser via script tags.

I also know of one application that uses this to good effect generating dynamic .doc files, wherein the doc template is saved in XML format, and by including the file, runtime CFML expressions are processed into the resulting .doc file. This is really pretty cool.

Adobe in their infinitesimal wisdom have decided to prevent this functionality by default. Yeah, now 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."
(Note: this was changed to compileextforinclude, by the time ColdFusion 11 was actually released).

Not to put too fine a point on it, but... Vamsee... what the hell are you on about? What security measure? What security are you protecting against here? What's the use case?

ColdFusion 11: first bug. Bad bug.

G'day:
Well that didn't take long.

One can no longer <cfinclude> any sort of file except a CFML file. EG:

<cfinclude template="junk.js">

This yields:

Invalid template junk.js provided for CFINCLUDE tag.

CFINCLUDE tag only supports including ColdFusion templates.
The error occurred inC:/apps/adobe/ColdFusion/11beta/gettingstarted/cfusion/wwwroot/shared/misc/junk/junk.cfm: line 1
1 : <cfinclude template="junk.js">

ColdFusion 11: "Getting Started Server"

G'day:
The first seemingly good thing that ColdFusion 11 offers is a "Getting Started Server", which is an installation-free version of ColdFusion server. It's just a zip file.

I'm downloading it now (it's still 282MB, but that's much smaller than the 597MB for the full installer)...

ColdFusion 11 has gone public beta...

G'day:
Just quickly... I have nothing really to report on this yet, but this is just a heads-up: ColdFusion 11 has just gone beta, and is available to download from Adobe: "Download Adobe ColdFusion Project Splendor and ColdFusion Builder Project Thunder".

The first ingteresting thing... there is a separate "getting started" install, which is just a zip file. Hopefully it's equivalent to Railo / OpenBD's express install, which is simply a matter of unzipping and running. I'm downloading it now, so will report back soon.

I am gonna start hammering it as soon as I can get it installed, and will report back with any meritworthy findings.

Stay tuned.

--
Adam

TestBox, BDD-style tests, Railo member functions and bugs therein

G'day:
One of the promised features of ColdFusion 11 is to bring "member functions" to ColdFusion's inbuilt data types. Railo's already had a good go at doing this, and has reasonably good coverage. See "Member Functions" for details.

One concern I have is whether ColdFusion 11 will implement these the same way as Railo already has. I mean... they should do, there's not much wriggle room, but who knows. If there's a way to do it wrong, I'm sure Adobe can find it. With that in mind, I want to be able to run through some regression/transgression tests on both systems once ColdFusion 11 goes beta, so in prep for that, today I knocked out some unit tests for all the struct member functions.

What I did is to go into the ColdFusion 10 docs, go to the "Structure functions" section (to remind me what all the functions were), and write unit tests for the whole lot. I used the ColdFusion docs rather than the Railo ones because the CF10 docs are more comprehensive than Railo's (this is an indictment of Railo's docs, not a recommendation for the ColdFusion ones, btw!), plus I wanted to make sure I covered any functions Railo might have overlooked.

To make this more interesting (because, let's face it, it's not an interesting task; either to undertake, write up, or for you to read about!), I decided to have a look at TestBox's BDD-inspired testing syntax. The short version of this side of things is that I rather like this new syntax.  I don't think it's got anything to do with BDD (which is an approach to documentation and test design, not a syntax model), but it's interesting anyhow.

Anyway, stand-by for a raft of code (there's a Gist of this too: Struct.cfc):