Showing posts with label Adam Tuttle. Show all posts
Showing posts with label Adam Tuttle. Show all posts

Sunday 20 October 2013

CFML: Threads, callbacks, closure and a pub

G'day:
I'm over in Ireland this weekend, and am doing my normal Sunday afternoon activity of sitting at Shannon Airport drinking Guinness, having finished my business early, so have a 4h wait in departures before my flight even considers boarding. Today's excitement here was the 500-odd US Army squaddies in transit to or from what I presume was Afghanistan. It makes a change from being the only person in the place, which was the case two weeks ago (other than shop staff, that is). Last night I killed some time in the pub too, during which I knocked out some quick code, to solve a problem I invented for myself to kill time. Here's the result.

A week or so ago Luis started an interesting thread on the Railo Google Group: "Add closure support to blocking operations to allow them to be non-blocking operations.". The summary of which is:

[...]I propose adding closure callback support to the following functions/operations so they can be processed natively in the background (non-blocking) and then call back when done.

FileRead
FileWrite
[...]
etc

Basically any operation that can block a network or local resource.  Imagine doing this:

fileRead( file, function(contents){
  process file here in the background once it is read.
});
[...]
The bits I omitted ([...]) are simply for abbreviation, and preserve the gist of his suggestion. This is a reasonable idea in general, but - as I go on to say in the thread - I don't think the suggested approach is very good for a coupla reasons. It's not bad, but it just seems a bit "embryonic" to me. But this is fine, this is what discussion forums are for.

My suggested approach would be more all-encompassing. Why limit this functionality to a subset of predetermined built-in functions? What about other built-in operations that might be slow, but otherwise doesn't need to interact with the rest of the code subsequent to it in the request? What about custom code that is similar? It makes little sense to me to "hard-code" this sort of behaviour to specific operations, to me.

A better solution would be to provide a general mechanism that can be used by any code to background-thread its execution, and fire callbacks on completion, failure etc, so as to kick off the next process, or flag-up that the process has completed.

Then it occurred to me that I thought I could knock a solution out to this using a single function. Not a very complete solution, but a solution nevertheless.

So sitting at the bar last night, over the course of four Guinnesseses, I came up with this lot:

Tuesday 1 October 2013

ColdFusion: Tirade averted... (update: no, actually: tirade)

G'day:
Last night someone from the community directed me at this issue on the bugbase: "Updating a task via cfschedule resets task to defaults". Neither of us could believe what Adobe had said to justify themselves. Fortunately in the interim cooler heads have prevailed, and they're on the case, but - dammit - I want to mention this anyhow.

The story with this bug - and it's a bug, Uday - is this:

If you are updating a scheduled task via the cfschedule tag it is possible for some of the task info to be reset back to default. For example, if task had an eventhander configured and cfschedule was used to update task but eventhandler attribute was not used then eventhandler would be set to blank. The eventhandler attribute is just one example as this affects other attributes equally.
So that's a bit rubbish.

Last night, the response from Adobe - via Uday Ogra - was this:

This is by design. As this action re-creates the schedule task. For updating particular attributes of an existing task it is recommended to use admin UI
This is yet another example of Adobe people being bloody jobsworths, IMO. I am gobsmacked by the stunning ignorance of Uday's justification here on two levels:
  • Who cares if it's by design: it's poor, lazy design. I'd be cool with this is Adobe went "oh yeah... oops", but to try to justify this away with "oh, it's meant to be like that" is pathetic. Indeed if you actually went out of your way to design something like that it doubles the question marks over your capabilities here: introducing a bug during development is one thing; specifically deciding to design something this poorly is unbelievable. Do you mean to say you sat down and went "right, when one uses this functionality to do an update, we'll blow away all the settings to didn't specifically set for update. Yeah: that's what people will want". Shudder.
  • What sort of bloody moronic advice is "as an alternative, use the UI". How is that gonna help us in our code? What sort of completely detached from reality suggestion is that? How is it a solution to a coding problem to suggest "use the UI instead".

Friday 26 July 2013

Recognising the people who help me with this blog

G'day:
Adam Tuttle (that's twice today) was quipping last that I'd mentioned him twice on the blog on Weds, and I should try for three times y/day (which failed: just the one mention, sorry). Anyway, as a joke back I said I should tag my articles with the people who I mention - these are usually people who have helped me, or caused me to write the article - and whoever is at the top of the list is automatically on my "give them beer next time I see them" list.

And then I thought... well why not? People do help me out and inspire me to write, and I appreciate it. So I did go through all my back articles last night, and tagged them up with the people I have mentioned in them, and I will continue to do so. So there are people's names listed at the bottom of the article on the "tags" bit, and the tag cloud thing on the right hand side also lists a bunch of people amongst the other tags I've got. Now there's been a whole swag of people tagged up, and the tag listing became unhelpful with every tag displayed, so you don't get a mention on the right unless you've got 3 mentions (or are Chris who only had two mentions until now, but as he wrote my most popular article, I decided to list his anyhow. And now he's got his third mention anyway).

Sean's currently at the top of the leaderboard, and there's a fair gap back to the rest of the pack.

Anyway... cheers y'all for your help along the way.

--
Adam

ColdFusion hoists VAR declarations

G'day:
Whilst messing around with how scopes in functions in ColdFusion work, I came across something I didn't know: like Javascript, ColdFusion hoists its VAR declarations. This could be common knowledge, but I certainly didn't know.

Here's some code that shows how an unscoped variable within a function interacts with a samed-named variable in the arguments scope, and to what unscoped references refer.

Update:
Ray pointed out the way I had originally done the code was very hard to read (harder than usual ;-). I'd tried to take a sort of two-column approach so all the writeOutput() statements were off to the right next to the statement they were outputting stuff for, not underneath. This made it much easier to follow the code in a text editor, but it looked whack when it was in the blog. I didn't notice when I was proofreading. Anyhow, I've sorted it out now. Cheers for the nudge, Ray. And note to any other readers: do let me know if I screw anything up like this!


function f(){
    writeOutput("Top: arguments: #arguments.foo#; unscoped: #foo#<br>");
    var foo    = "var";
    writeOutput("After var: arguments: #arguments.foo#; unscoped: #foo#<br>");
    foo        = "unscoped";
    writeOutput("After unscoped: arguments: #arguments.foo#; unscoped: #foo#<br>");
    return {arguments=arguments,foo=foo};
}

result = f(foo="arg");
writeDump(var=result);

Thursday 25 July 2013

CFML implementation of Array.reduce()

G'day:
I've knocked out a quick arrayReduce() UDF, which I'll post on CFLib once I get some code review feedback (if any) on it. I'd appreciate sets of eyes on it, if you had time.

Update:
Adam Tuttle (only one mention today mate, sorry) offered some advice on Code Review, which I have taken onboard. This is the second iteration of the function. I have also updated the entry on Code Review too.

For the sake of completeness, here's the code, but pls feed-back on the Code Review page, as per link above:

/**
* @hint CFML implementation of Array.reduce(), similar to Javascript's one ref https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
* @array Array to reduce
* @callback Callback function to use to reduce. Will receive the following arguments: element (of current iteration of the all), index, array, (optional) result (of preceeding call to callback())
* @initialValue The initial value to use to start the reduction
*/
any function arrayReduce(required array array, required any callback, any initialValue){
    var startIdx = 1;
    if (!structKeyExists(arguments, "initialValue")){
        if (arrayLen(array) > 0){
            var result = callback(array[1], 1, array);
            startIdx = 2;
        }else{
            return;
        }
    }else{
        var result = initialValue;
    }
    for (var i=startIdx; i <= arrayLen(array); i++){
        result = callback(array[i], i, array, result);
    }
    return result;
}

If created a Gist with full(-ish) unit test coverage, too.

Ta.

--
Adam

Wednesday 24 July 2013

Two incidents of Adobe support that I noticed today

G'day:
Here's a dichotomy.

Whilst on the subject of things in ColdFusion that don't work

G'day:
I also found this one whilst testing Adam's code (as per previous article).

This doesn't work in ColdFusion (9.0.1):

a = 1;
b = 2;
writeOutput("Result: #a == b#");

I get:

Error Occurred While Processing Request

Invalid CFML construct found on line 4 at column 25.

ColdFusion was looking at the following text:=


But this is fine:
a = 1;
b = 2;
writeOutput("Result: #a EQ b#");

Obviously both should work fine. And they do on both Railo and OpenBD.

That's all I have to say on that. Bug raised: 3600686.

--
Adam

Thursday 18 July 2013

1

G'day:
I'm a bit late with this as it happened a week or so ago, but I just noticed I've been prattling away on this blog for a year now.

Apropos of nothing, here's some mostly useless information about this blog.

I said in one of my earlier articles that I've learned more about ColdFusion since I started this blog than I had in the preceding few years. This continues to be the case, and I've learned a bunch of good stuff about Application.cfc, ColdFusion regexes, JSON (grumble), REST, interfaces (in general, as well as ColdFusion's inplementation of them), and various other odds 'n' sods. Even some web sockets stuff, whilst troubleshooting that security issue from a coupla weeks back. I've also used Railo a lot more, and had a look at Coldbox. Beyond ColdFusion I've also started dabbling with PHP and Ruby. It's been cool! I hope some of it was useful to you, or at least slightly interesting. Or killed some time whilst you tried to decipher what I was wittering on about.

To close, I'd like to say special thanks to a few people whose participation in this blog has been helpful, interesting or thought-provoking. In no particular order, and it's certainly not an exhaustive list:
  • Chris Kobrzak
  • Sean Corfield
  • Andrew Myers
  • Bruce Kirkpatrick
  • Brad Wood
  • Andrew Scott
  • Adam Tuttle
  • Ray Camden
  • Gavin Pickin
  • Jay Cunnington
  • Simon Baynes
  • Duncan Cumming
  • Brian Sadler
There's been a bunch of great input / correction / sanity-checking / bullshit-detection done by a heap of other people too.  Cheers to everyone who's participated here.

And now on to year 2...

--
Adam

Thursday 20 June 2013

Is ColdFusion's REST implementation more verbose than it needs to be?

G'day:
I've been using some REST web services at work recently (CFML calling .NET ones; I'm just working on the CFML side of things, unfortunately), and also pottering around with ColdFusion 10's REST stuff at home occasionally. And then I wrote my "things I ain't researching" article, and one of the entries in that was to look more at CF's REST implementation more thoroughly, as well as Taffy and Relaxation. That in turn reminded me of a thread on Twitter in which Sean was denigrating ColdFusion 10's approach to REST, instead espousing a by-convention approach to things, or just in general not having the REST config alongside the code itself. I don't necessarily agree with him on the latter (I don't necessarily disagree, either!), but it's thought-provoking.

One thing that persisted in my mind is that it seems like there's a lot of horsing about making a method REST-callable, and after discussing a conventions-based approach with both Sean and separately with Adam Tuttle, I turned my mind to that.

God my writing is awful today, sorry. Slightly hungover. Bear with me.

OK, so here's a CFC and a method:

component {

    public string function greet(required string name) {
        return "G'day #arguments.name#!";
    }
}

The minimum I seem to be able to get away with to "RESTify" this is:

component rest=true {

    remote string function greet(required string name restargsource="query") httpmethod="get" {
        return "G'day #arguments.name#!";
    }
}

Thursday 13 June 2013

What do I want to see in ColdFusion 11?

G'day:
I'm suffering a bit from motivation paralysis at the moment... I'm not suffering writer's block: if anything the opposite, I've got about a dozen articles on the go at the moment. Or maybe that means I've got writer's block a dozen times over? Dunno.

Anyway, this is just an easy article to bang out: listing a bunch of stuff.

Friday 18 January 2013

How cool are the Railo guys?

G'day:
Just a quick one. Check this out. I was chatting with Adam Tuttle last night about some differences we'd noted in how ColdFusion and Railo seem to implement the hashCode() method for their respective struct implementations.  Here's some code (as per the thread I link to above):