Friday 27 February 2015

JS: opinions solicited regarding passing data values from server to client

G'day:
Just quickly.

Almost all of our JS is in separate JS files, and we try to take as much of an OO approach to our JS as is sensible in such a OO-hamstrung language. We do have separate "class" files (methods, stateful properties etc) and then script files which are used for event handlers when bootstrapping the page (creating said objects, etc).

Our JS inclusions would typically be along these lines:

<script src="/me/adamcameron/someapp/somepackage/SomeClass.js"></script>
<script src="/me/adamcameron/someapp/codeThatUsesSomeClass.js"></script>

Where:

// codeThatUsesSomeClass.js
var obj = new SomeClass(initParam, anotherInitParam);

// do stuff with obj

Guerilla tactics to force Adobe's hands

G'day:
It's Friday afternoon and I'm in a cheeky mood.

Thursday 26 February 2015

CFML: Dan Kraus - "more CF devs need to leave The Shire for a bit"

G'day:
I'm going through my in box today, catching up with all the comments ppl have made that I've not replied to.

Dan Kraus made a comment the other week on that article "Lucee: does its future include CFML?". It and its follow-up warrant repeating and more eyeballs on it, so I said I'd promote it to an article so people would def notice it. I should have done this back when the article was fresh, but got sidetracked.

Wednesday 25 February 2015

CFML: trying to understand accessors

G'day:
I've decided I'm the wrong person to be writing a book on CFML, given I clearly don't bloody understand even the fundamentals of it, in places. And this is after using it daily for over a dozen years.

I thought I understood CFCs in CFML inside out. No.

Dom posts interesting feedback

G'day:
I was gonna just bury this as a response to a comment in the original article, but I've decided Dom's comment is really excellent, so I'm promoting his comment & my feedback to be an article.

This was in reaction to my "Regarding codes of conduct and the nature of forum participation" article from a few days ago.

Monday 23 February 2015

Regarding codes of conduct and the nature of forum participation

G'day:

There's been discussion about a Code of Conduct for the Lucee Google Group. Well without having the bottle to actually describe it as such... indeed going so far as to suggest that isn't what this thread was floating: "Tone and community guidelines".

Despite knowing full-well that some of the points are directed at least partially (or possibly entirely) at me, I think it's an appropriate idea. Sorta.

That said, I'd like to have a look at a coupla issues that came up in that list of bullet points, from comments on the thread, and in general.

Sunday 22 February 2015

ColdFusion: testing the recent updates

G'day:
As I'd raised a few of the issues Adobe claims to have fixed in these recent ColdFusion updaters, I figure I should probably do some testing for them.

First up, ColdFusion 11 update 5

Friday 20 February 2015

Off topic: sorry, this needs repeating

G'day:
I know this will mean nothing to my readers from the Americas.

Adobe ColdFusion Team getting their act together?

G'day:
On the heels of ColdFusion update 4 coming out yesterday, I see that there is now ColdFusion 10 Update 16 prerelease build available (37 fixes), as well as ColdFusion 11 Update 5 prerelease build now available (119? fixes). Good work.

Note that these updates are still only pre-release quality, so only fit for testing. Do not put the into production.

Thursday 19 February 2015

ColdFusion 11 update 4 released

G'day:
This'll be quick as I'm sitting in some dodgy motel room in Wellington, in the dark, with internet that is hamster-wheel powered.

I just noticed ColdFusion 11 update 4 has finally been released. That took longer than it should have. I suspect Adobe forgot they hadn't released it.

This is the one that basically fixes everything that updater 3 broke. So not exactly a forward move, but hey. At least Adam Tuttle will be pleased the ?: will be working again.

Oh, and make sure you pay attention to this guidance:



It's great to see they still haven't managed to automate that step.

Obviously if you install this, put it on a test machine first, and do your unit and regression tests. Do not put it straight into production.

The details are here, and you install most of it via CFAdmin.

--
Adam

Wednesday 18 February 2015

I post a Lucee question on Stack Overflow

G'day:
Maybe you can help with this: "Associating child tag data with grandparent tag using CFC-based custom tags"?

Clean Code

G'day:
Not something by me, but just a heads-up to go read one of Gav's blog articles: "CommandBox - Commands can be Clean Code Too". Don't worry about the fact it's about *Box stuff, that's irrelevant. It's a good practical demonstration of applying Clean Code concepts to CFML code.

--
Adam

"ColdFusion Interfaces": a question from a reader

G'day:
One of my readers hit me up with a question about interfaces in CFML:

[...] I would like to ask you a question please. I was unable to find a recent good article by you or anyone else about this topic.

ColdFusion Interfaces; do you rekon using them or not please? Please provide why you would not reckon using ColdFusion Interfaces. [...]

I started looking at this yesterday which explains yesterday's blog post, but I got sick of writing before I had a chance to actually answer. Now I'm sitting at my folks' place (sans rat, today), in the middle of a power outage. Fortunately my battery is charged up, and I can answer this one without any research, so here we go.

Tuesday 17 February 2015

CFML: Interface fulfilment via mixin

G'day:
So a day after I say I'm gonna leave this blog be for a while, I'm back. It's like how I said I was ditching CFML and going to PHP on this blog. Basically I just lie, don't I?

Well I'm sick of writing this bloody book for the day, and I've got a reader question to answer which I decided to follow up on. But first I did some prep work and found something moderately intriguing. Well as intriguing as CFML's interface implementation gets, anyhow.

Saturday 14 February 2015

Snooze

G'day:
This is just a heads-up. I intend to put this blog on hiatus for the next few weeks. I'm on holiday at the moment, and I'm also trying to break the back of this CFML book I'm writing (slowly... only two chapters drafted so far). I'm also finding a lot of my time needs to be sunk into the Lucee mailing list at the moment (for better or for worse).

If a blog topic springs to mind and I feel I need to write it up immediately I will do so, but I'm not going "ooh lummy... I haven't written anything on the blog recently..." and letting it bother me.

Oh yeah, and there's also too much cricket to watch and beer to drink out here in NZ. Today is South Africa v Zimbabwe and India v Pakistan, which I'm watching with me Mum & Dad.

Righto.

--
Adam

Trying to get clarification about the status / future of Railo

G'day:
I figured I had better try to find out the official word from The Railo Company as to the status of the Railo open source project, and what the future for it is likely to be. I have written this open letter to Railo:

Saturday 7 February 2015

Lucee: does its future include CFML?

G'day:
There's a lively thread on the Lucee Google Group at the moment: "Outsider Perspective". There's a fair bit of cruft in there... OK, it's mostly cruft... but there was one very interesting comment from Micha:

ACF compatibility
[...]
So what could be the medium for Lucee, that is very simple, the medium are templates (.cfc,.cfm).
What if Lucee acts different depending on the file extension.
So all templates with .cfm and .cfc extensions are still handled the old way, but files with the extension .lucee are handled in a modern way. this gives you the opportunity to still use your old code but you can extend it with new one and you have no confuguration nightmare anymore!

My emphasis, obviously.

Hmmmm. I tried to get Micha to elaborate for a public audience, but he hasn't been forthcoming yet, leaving it up to community speculation. Most of the speculation thusfar has been around what the file extension should be (yes, really), and no real grist. I've been holding off on that thread until Micha antes-up a bit.

However, on this blog... I'll allow myself to speculate away like nobody's business...

Ray Camden says "CFML is dead"! Kinda. Not really

G'day:
I can't believe it! Ray Camden just said CFML IS DEAD!!!!

PHP: objects as arrays, and can CFML benefit from the concept?

G'day:
We had a situation at work the other day in which we needed a collection class, I think it was Properties (that's in the real estate sense of "property", not the OO one: I work for an online travel company, and this was part of a search result). This is distinct from a single Property which represents a single hotel / hostel / whatever.

Using CFML we would have used a record set to represent this, and in PHP we'd generally represent this as an array (of individual Property objects). However the collection of Properties needed other behaviour as well: storing the minimum price per night, highest rating percentage etc. So we're definitely wanting an object of some description to keep the array of properties and other... erm... properties (in the OO sense now) defined together in the one place.

A traditional approach might be this (pseudo code):

class Properties {
    Property[] properties;
    Decimal lowestPrice;
    Decimal highestRating;

    // and some accessors etc
}

And that would have been fine. However I rather liked the notion of instead of having to pluck the properties array out of the object before doing anything with it... just to use the object itself as an array. C# has an idea of Indexers, and I was pretty sure PHP had at least an Iterable interface, and perhaps some other bits and pieces that might work as well.

Indeed it does, and I was able to come up with an object which one can treat like an array. Almost.


// Collection.php

class Collection implements Iterator, Countable, ArrayAccess
{
    protected $collection;
    protected $index;

    public function __construct($array){
        $this->collection = $array;
    }

    public function getCollection() {
        return $this->collection;
    }

    public function current() {
        return $this->collection[$this->index];
    }

    public function key() {
        return $this->index;
    }

    public function next() {
        ++$this->index;
    }

    public function rewind() {
        $this->index = 0;
    }

    public function valid() {
        return array_key_exists($this->index, $this->collection);
    }

    public function count() {
        return count($this->collection);
    }

    public function offsetExists($index) {
        return array_key_exists($index, $this->collection);
    }

    public function offsetGet($index) {
        return $this->collection[$index];
    }

    public function offsetSet($index, $value) {
        echo "offsetSet() called with [$index], [$value]<br>";
        if (is_null($index)) {
            $this->collection[] = $value;
        }else{
            $this->collection[$index] = $value;
        }
    }

    public function offsetUnset($index) {
        unset($this->collection[$index]);
    }
}

I've highlighted the method implementation that each of the Iterator, Countable and ArrayAccess interfaces require. These methods allow me to traverse through the object - as one would in a foreach() loop; "count" the elements in the object (eg: using count()); and set elements into the object's array using array notation.

Having implemented these interfaces, I no longer need to extract the array from the object to use, I can access it via the object itself.

Here I populate a test collection with Maori numbers 1-4:

$numbers = ['tahi', 'rua', 'toru', 'wha'];
$numbersCollection = new Collection($numbers);
printf('Collection after initialisation: %s<br>', json_encode($numbersCollection->getCollection()));
echo '<hr>';

Output:
Collection after initialisation: ["tahi","rua","toru","wha"]

Then loop over the object using a normal foreach() loop:

foreach ($numbersCollection as $number) {
   echo "$number ";
}
echo '<hr>';

Output:
tahi rua toru wha

I can also set elements in the array via either a direct index reference:

$numbersCollection[4] = 'rima';
printf('Collection after setting [4]: %s<br>', json_encode($numbersCollection->getCollection()));

Output:

Collection after setting [4]: ["tahi","rua","toru","wha","rima"]

and even via the shorthand append syntax:

$numbersCollection[] = 'ono';
printf('Collection after setting []: %s<br>', json_encode($numbersCollection->getCollection()));

Output:

Collection after setting []: ["tahi","rua","toru","wha","rima","ono"]

All that's reasonably good!

However from here, the behaviour leaves a bit to be desired. Firstly here's an example of where PHP's array implementation demonstrates itself as being a bit wanting. I tested removing an element:

unset($numbersCollection[2]);
printf('Collection after unset(): %s<br>', json_encode($numbersCollection->getCollection()));

The intent here is to remove the third element: toru. Here's what we get:

Collection after unset(): {"0":"tahi","1":"rua","3":"wha","4":"rima","5":"ono"}

OK, that ain't good. It's cleared the value and removed the element, but it's not reindexed the "array", so there's a gap left in the indexes. As a result the JSON encoder has gone "array? that's not an array, sunshine... erm, I better make it an object" (notice the curly braces, not the square ones, and the explicitly stated keys).

Initially I thought this was a glitch in my implementation, so I tested on a native array:

unset($numbers[2]);
printf('Array after unset(): %s<br>', json_encode($numbers));

Output:

Array after unset(): {"0":"tahi","1":"rua","3":"wha"}

That's pants. Amateurs. This is an artifact of PHP not understanding that there's a difference between an indexed array (indexed via sequential numbers) and an associative array (indexed on arbitrary key), which is a fairly fundamental implementation shortfall.

And it turns out PHP's implementation of the ArrayAccess interface is a bit hamstrung too. Well the interface implementation itself is OK, but then PHP's internal usage of the interface is... lacking. Here I use a native array function on my collection:

$uppercaseNumbers = array_map(function($number){
    return strtoupper($number);
}, $numbersCollection);
printf('Collection used in array_map(): %s<br>', json_encode($uppercaseNumbers));

And this yields:

Warning: array_map(): Argument #2 should be an array in Collection.php on line 101
Collection used in array_map(): null


Because... whilst PHP offers the interface, it doesn't itself actually expect the interface in its array functions:

array array_map ( callable $callback , array $array1 [, array $... ] )

Note that it expects an array for the second (and subsequent) arguments. Not an ArrayAccess. If PHP is going to offer an interface to enable objects to have array behaviour... it really ought to have gone the whole hog, and implemented an ArrayImplementation interface, and then expect one of those in all its array functions.

This is the story of PHP: they seem to have the ideas, but they don't seem to know how to do a thorough job of planning and implementing the ideas.



If it was implemented thoroughly... could this general idea be useful for CFML? I'm thinking of one unified interface that describes what one needs for native CFML array functionality to be able to operate on a collection object? What would be needed?

// Array interface
interface {

    // access
    any function get(required numeric id);
    void function set(required numeric id, required any value);
    void function remove(required numeric id);
    numeric function size();
    
    // traversal
    void function reset();
    void function next();
    any function current();

}

That should provide all the hooks native CFML would need to be able to use an object as an array (eg: using native array access syntax, functions, methods, and general language constructs such as for() loops).

I think this would be a pretty handy addition to CFML? I think CFML has always offered reasonable OO opportunities for CFML code, but it itself is pretty lacking in the OO department when it comes to interacting with that code. This is an example of this: its array functionality only works with native arrays. It should work with any object that has the behaviour of an array. Something CFML has in common with PHP then. Another thing.


One thing my colleague/mate Brian pointed out (this was in the context of the PHP code, not this CFML idea) is that if we're using a dynamic language, should we need to implement actual interfaces? There's a good case for duck typing here. Provided a class implements all the requisite methods to be able to be treated as an array, should the runtime simply not allow an object to be used in place of an array.

EG: for an object to be used in a foreach() loop, it needs to provide a next() and get() method (maybe a getKey() and getValue() method. Provided the object has those methods, it should be usable in that situation. Even more so in the CFML situation: the class doesn't need to have the methods specified... provided the method is there at runtime, that should be fine (for my PHP readers, in CFML one can inject new methods into an object at runtime). This is true language dynamicism at work. This is where CFML (and PHP) should be positioning themselves: get rid of the ceremony, and just crack on with the business of being a modern dynamic language.

For PHP, they need to get their act together and understand the difference between an indexed array and an associative array. However this is a fundamental language problem that is unlikely to be addressed. For CFML... there's an opportunity here to make the language a bit more cooler.

Thoughts?

--
Adam

Thursday 5 February 2015

Waitangi Day 2015

Tēnā koutou:
It's Waitangi Day again (see "Completely and utterly off-topic: Waitangi Day" & "Waitangi Day again"), and I'm about to go back to NZ for a few weeks, during which time I'm gonna be eyes-glued to the Cricket World Cup which is being cohosted by Australia and New Zealand. I've managed to scrounge tickets for NZ v Aussie and NZ v the Poms, which should be two of the better games in the tournament.

So here's some stuff about NZ cricket.

CFML: time for a CFML specification?

G'day:
I note that PHP has finally got itself a language specification: "Announcing a specification for PHP". I can't hep but think that having a proper spec for CFML would be beneficial for the CFML community too.

Monday 2 February 2015

Lucee: like a scene from Chinatown

G'day:
It's Google Groups [slap]... it's Discourse [slap]... it's Google Groups...

So, currently (although for how long, I don't know any more), the official Lucee community forum channel is back to being Google Groups again: https://groups.google.com/forum/#!forum/lucee

Whatever communications channel they use, I really think the Lucee people need to get their act together a bit as far as planning these decisions properly goes. It seems to me that Micha is hearing the first suggestion regarding something and just jumping on it immediately. This attitude needs to grow up a bit.

Still: let's put it down to teething problems. And in the long run, it won't end up mattering.

-- 
Adam

Sunday 1 February 2015

Lucee: hiccups when getting a new Express install running

G'day:
These are as much "notes to self" as anything else. Railo Express used to run on Jetty which was simply "unzip and run". Lucee express is now on Tomcat, and I think if one never had Railo / Lucee / Tomcat installed before it would also be "unzip and run", but I had a coupla hiccups along the way, so I thought I'd jot them down here to remind me what needs doing, and it might help other people if they get stuck too.