Showing posts with label Arrays. Show all posts
Showing posts with label Arrays. Show all posts

Wednesday, 4 November 2015

ColdFusion 2016: arrays now passed by reference

G'day:
There's not much to say about this one. ColdFusion is finally playing catch-up, and standardising its approach to passing complex objects.

Traditionally, ColdFusion has passed "simple values" (strings, numerics, dates, etc) by value, and complex objects (structs, queries, XML) by reference (provided one understands "pass by reference" with these caveats: "Complex data-types in CF, and how they're not copied by reference"). The one exception was arrays. Arrays were passed by value. Why? I don't bloody know.

Right from the outset Railo decided that was bloody daft and has never done this, and this has been inherited by Lucee.

Now ColdFusion has caught up, even if I think the specific implementation is lacking.

There is a new setting for Application.cfc, this.passArrayByReference, which one can set to true (the default is false). If one sets that, then the behavour of passed arrays is changed.

Let's have a look at some code running on ColdFusion 11:

function arrayToUpperCase(array){
    for (var i=1; i <= array.len(); i++){
        array[i] = array[i].ucase();
    }
    return array;
}

rainbow    = ["Whero","Karaka","Kowhai","Kakariki","Kikorangi","Poropango","Papura"];

rainbowInUpperCase = arrayToUpperCase(rainbow);

writeDump(var=rainbow, label="rainbow", format="text");
writeDump(var=rainbowInUpperCase, label="rainbowInUpperCase", format="text");

This simple code has a function which takes an array, upper-cases each element and returns it. Afterwards, we dump both the original and returned arrays:

rainbow - array

1) Whero 
2) Karaka 
3) Kowhai 
4) Kakariki 
5) Kikorangi 
6) Poropango 
7) Papura 
rainbowInUpperCase - array

1) WHERO 
2) KARAKA 
3) KOWHAI 
4) KAKARIKI 
5) KIKORANGI 
6) POROPANGO 
7) PAPURA 

As you can see, when we modify the passed-in array, it does not impact the original array. Constrast this with the same operation with a struct:

function structToUpperCase(struct){
    for (var key in struct){
        struct[key] = struct[key].ucase();
    }
    return struct;
}

rainbow    = {red="Whero", orange="Karaka", yellow="Kowhai", green="Kakariki", blue="Kikorangi", indigo="Poropango", purple="Papura"};

rainbowInUpperCase = structToUpperCase(rainbow);

writeDump(var=rainbow, label="rainbow", format="text");
writeDump(var=rainbowInUpperCase, label="rainbowInUpperCase", format="text");

rainbow - struct

BLUE: KIKORANGI
GREEN: KAKARIKI
INDIGO: POROPANGO
ORANGE: KARAKA
PURPLE: PAPURA
RED: WHERO
YELLOW: KOWHAI
rainbowInUpperCase - struct

BLUE: KIKORANGI
GREEN: KAKARIKI
INDIGO: POROPANGO
ORANGE: KARAKA
PURPLE: PAPURA
RED: WHERO
YELLOW: KOWHAI

As you can see, because structs are passed by references, the argument in the function references the same struct as in the calling code, so changes to the argument are reflected in the original.

Saturday, 7 February 2015

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.

Tuesday, 18 November 2014

What should CFML's deleteAt() method return?

G'day:
This will be quick, as I'm out of time before I'm due to start work.

As I mentioned in my earlier article ("Weekend quiz: my answer (CFML version)"), Railo's (and ColdFusion's for that matter) Array.deleteAt() method returns a pointless boolean, rather than something useful. What do you think it should return?

Tuesday, 22 October 2013

Follow-up to a "not a bug" status from Adobe: arrayFindNoCase() returns false negatives

G'day:
About a year ago I raised a ticket observing that arrayFindNoCase() doesn't really work so reliably: 3316776. A coupla weeks ago it was marked as "not a bug", which I find rather bemusing - as there's definitely buggy behaviour - but not as bemusing as the explanatory feedback from Adobe.

Saturday, 28 September 2013

arrayEach() could stand some improvement

G'day:
I'm going to lobby to get Saturday renamed "Sidetrackday". I sat down to write up a bunch of stuff one Ruby, and so far have written some CFML, some JS, some PHP and some Ruby... but not the Ruby I was intending do. Oh well.

I've touched in the past on my opinion that ColdFusion 10's new arrayEach() function is rather poorly/superficially implemented (here too), but today decided to check out how other languages deal with the same thing, and try to conclude what's the best approach for CFML to take.

So what's the story with arrayEach()?

Digression:

Those docs, btw, are frickin' useless:
  • Where's the code example?
  • Where's mention of the arguments passed to the callback? How many? What are they?
  • See also "other closure functions". Should that be a hyperlink, or is it just meant to be a pointless exercise of stating the obvious?
  • Category "Closure functions". Again: no link. And there isn't a category elsewhere in the docs "Closure Functions".
  • The function argument doesn't need to be inline. It just needs to be a function reference.
There's more wrong about those docs that there is that is right. That's quite an achievement.

End of digression.

So in lieu of the docs explaining this, what does it do? Here's a baseline demonstration:

rainbow = ["Whero","Karaka","Kowhai","Kakariki","Kikorangi","Tawatawa","Mawhero"];

arrayEach(
    rainbow,
    function(v){
        writeOutput(v & "<br>");
    }
);

This outputs:

Whero
Karaka
Kowhai
Kakariki
Kikorangi
Tawatawa
Mawhero


Basically what arrayEach() does is loop over the passed-in array, and then passes the value of each element to the callback function. The callback function receives one argument, that value. That's all it receives. And it can return a value if it likes, but nothing is expecting the value, so for all intents and purposes, the callback's method signature is:

void function callback(Any value)

Superficially that's fine. However it's a very isolated-element-centric approach. What I mean is that as far as the callback goes, the value it receives - for all intents and purposes - is not an element of an array, it's simply a value. You cannot act on that value in its content in the array. What? Well let's say I want to transform the array's elements. A simple example would be to upper-case the elements of an array of strings. Maybe like this:

rainbow = ["Whero","Karaka","Kowhai","Kakariki","Kikorangi","Tawatawa","Mawhero"];

arrayEach(
    rainbow,
    function(v){
        return ucase(v);
    }
);

writeOutput(rainbow.toString());

Well... no. Remember how I said that nothing is listening for a return value? Well it's not. So you're returning your upper-cases element back to the ether. v is a disconnected value here: the callback doesn't get it as part of the array, it just gets it as a value.

Sunday, 28 July 2013

OK, I'm very confused: arraySort() with a callback...?

G'day
I'm sitting at Shannon Airport awaiting my return flight to London, and killing time via Guinness and responding to comments on my blog. There are no little old catholic ladies here today to keep me bemused, indeed it's very quiet.

Anyway, this is the comment I'm currently trying to reply to:

I executed the example you have showed above for customised sorting using arraysort function, but i didn't get the same result. The output i got was the array that i defined in the code. I can't understand why its not happening for me.
 The code in question is this:


a = [
    {firstName="Witi", lastName="Ihimaera"},
    {firstName="Patricia", lastName="Grace"},
    {firstName="Alan", lastName="Duff"},
    {firstName="Lee", lastName="Tamahori"},    // OK: not an author
    {firstName="Keri", lastName="Hulme"}
];

arraySort(
    a,
    function (e1, e2){
        return compare(e1.lastName, e2.lastName) > 0;
    }
);
writeDump(a);

Monday, 17 September 2012

Arrays in Railo (appendix to the earlier 4-part series)

G'day:
Just when you thought it was safe... here's some more on arrays in ColdFusionRailo. I've already blathered on about the ins and outs of arrays in ColdFusion... well more like arrays in CFML as I cover some stuff in not only ColdFusion but also Railo and a bit on OpenBD too:
But a comment from Gert against one of my blog posts was tucked away in the back of my mind... Railo does some of its own thing when it comes to arrays (and structs, lists, etc).

Friday, 31 August 2012

Good things about Railo (#1) - CFLOOP

G'day, this is just a quick one.

In my last post I was discussing looping over arrays, and how Adobe messed-up their implementation of looping over an array with <cfloop> a bit (3321646).  Overnight, Gert from Railo added a comment, drawing my attention to Railo's handling of same.  And I gotta say I'm impressed.

Thursday, 30 August 2012

Arrays in CFML (part 4)

G'day:
As the title suggests, this is part four of a series of articles I've written about arrays in CFML. So far I've covered what an array is and how to create them, plus two articles covering all the functions in CFML which specifically work with arrays.
As well as these functions that are specifically implemented to maintain & manipulate arrays, there are a bunch of other functions relating to other data types that use arrays. I'm going to cover those in this article. I'll break them down by the data-type they relate to.  I'm not going to do indepth coverage of how the functions work, because I'll eventually cover them when I give the various other data types the same treatment I'm giving arrays here.  EG: I'll discuss structFindKey() thoroughly when I do an exploration into "Structs in ColdFusion" (OK, so you've been fore-warned... there's more of this to come! ;-).  I'm just gonna dwell on the array`ed-ness of the relevant functionality.

Thursday, 23 August 2012

Arrays in CFML (part 3)

G'day:
This article finishes up the coverage of array functions in CFML (there's more to discuss than just the functions: I'll get to that stuff in yet another article). Most of the array functions were covered in an earlier article, and I'm just finishing of the rest of them here. The functions here haven't been put in a separate article for a good reason: it's just that I'm daft and forgot to put then in the earlier article that should have included them. I dunno how I missed them of the list initially, as I based my "todo list" on the list of functions on the "Array Functions" page from the CF docs. Like I said: I'm just daft. Anyway... here they are.

Thursday, 16 August 2012

Arrays in CFML (part 2)

G'day:
In this article, which is part two in an ongoing series, I'll discuss the various functions CFML ships with for working with arrays. The first part described what an array is, and how to create them.

The online docs cover each of these functions too, but the coverage is pretty superficial. They cover all the syntax options and give a code example, but they don't go beyond that. Having been around the block a few times (and thus... err... ending up back where I started.. hmmmmm...), I've picked up the odd but of insight, and have explored some of the idiosyncrasies of CFML that isn't covered in the docs. I shall try to discuss why one might want to use a given function, rather than just cataloguing that it exists (which is all the official docs seem to set out to do, at times).

The docs are good for something though: they do act as a good lookup of what's available, so go have a look at then after yer done here.

Anyway, enough waffle...

Sunday, 12 August 2012

Complex data-types in CF, and how they're not copied by reference

G'day
I've got part 2 of the array discussion underway, but I'm just going to digress slightly to write some notes up about how CFML deals with assigning and passing-around complex objects.

Again there's probably nothing new here for most bods out there, but hopefully it'll be useful to some people.

OK, so first up, there are a number of data types in CFML:
  • string (including lists)
  • date
  • boolean
  • numeric (including both integer and floating point)
  • array
  • struct
  • query
  • XML
  • objects (specifically native CFML ones, ie: component instances)
  • [others]
Included in "[others]" are stuff like file handles, images, spreadsheets, FTP connections, and stuff like that... there's a whole bunch of them, and I won't try to list all of them because I'll forget something, which'll mean someone will need to add a comment to point this out. So I'm just saving us all some time.

Saturday, 11 August 2012

Arrays in CFML (part 1)

G'day:
I'm going to write up my understanding of how arrays work in CFML. This is a mundane topic in any programming language, but it's also absolutely critical, and having a good handle on how they work is very important. I will say up front that if you're a seasoned CFML developer that there probably won't be anything in here you don't already know.

Friday, 27 July 2012

Why do CFML arrays start at 1 instead of 0?

G'day
A few weeks ago whilst investigating something completely unrelated, I came across an interesting thread on StackOverflow, in which someone had asked why ColdFusion arrays start at index 1 rather than index 0 like other languages do.

This was an old thread, but my thoughts on it were a bit different from the others thusfar offered, so I wrote up my own point of view. Whilst writing it I started to think "I wish I had a blog for this sort of thing, rather than posting it on an old thread on StackOverflow"... and it was that thought that culminated in me finally starting this blog.

Anyway, I realise it's a bit of a duplication, but I'm "reclaiming" the post for myself. Here it is.