This might be old news, but it's something I didn't know until today. Railo supports function return values and arguments of type array-of-something, eg:
function acceptArrayOfSamples(required Sample[] samples){
// etc
}
Sample[] function returnArrayOfSamples(){
return [new Sample(), new Sample()];
}
Where sample is a CFC, eg:
//Sample.cfc
component {
}
It also works (kinda) for inbuilt types too, like strings and numerics.
I had a look at how well this stuff works, writing these test functions:
// functionsToTest.cfm
private any function acceptArrayOfSamples(required Sample[] samples){
return samples;
}
private Sample[] function returnArrayOfSamples(required array samples){
return samples;
}
private any function acceptArrayOfStrings(required string[] strings){
return strings;
}
private string[] function returnArrayOfStrings(required array strings){
return strings;
}
private any function acceptArrayOfNumerics(required numeric[] numerics){
return numerics;
}
private numeric[] function returnArrayOfNumerics(required array numerics){
return numerics;
}
private any function acceptArrayOfStructs(required struct[] structs){
return structs;
}
private struct[] function returnArrayOfStructs(required array structs){
return structs;
}
These functions either accept an array of various types (Samples, strings, numerics, structs), or return same.
I've written some unit tests to see how well this lot works:
// TestArraysOfObjects.cfc
component extends="mxunit.framework.TestCase" {
public void function beforeTests(){
variables.arrayOfSamples = [new Sample(), new Sample()];
variables.arrayofSubSamples = [new SubSample(), new SubSample()];
variables.arrayofNotSamples = [new NotSample(), new NotSample()];
variables.arrayOfStrings = ["array", "of", "strings"];
variables.arrayOfNumerics = [-1, 2.2, pi()];
variables.arrayOfStructs = [{one="tahi"}, {two="rua"}, {three="toru"}, {four="wha"}];
include "./functionsToTest.cfm";
}
public void function testAcceptArrayOfSamples(){
acceptArrayOfSamples(arrayOfSamples);
}
public void function testReturnArrayOfSamples(){
returnArrayOfSamples(arrayOfSamples);
}
/**
* @mxunit:expectedexception expression
*/
public void function testAcceptArrayOfSamples_withStrings(){
acceptArrayOfSamples(arrayOfStrings);
}
/**
* @mxunit:expectedexception expression
*/
public void function testReturnArrayOfSamples_withStrings(){
returnArrayOfSamples(arrayOfStrings);
}
public void function testAcceptArrayOfSamples_withSubSamples(){
acceptArrayOfSamples(arrayOfSubSamples);
}
public void function testReturnArrayOfSamples_withSubSamples(){
returnArrayOfSamples(arrayOfSubSamples);
}
/**
* @mxunit:expectedexception expression
*/
public void function acceptArrayOfSamples_withNotSamples(){
acceptArrayOfSamples(arrayOfNotSamples);
}
/**
* @mxunit:expectedexception expression
*/
public void function testReturnArrayOfSamples_withNotSamples(){
returnArrayOfSamples(arrayOfNotSamples);
}
public void function testAcceptArrayOfStrings(){
acceptArrayOfStrings(arrayOfStrings);
}
public void function testReturnArrayOfStrings(){
returnArrayOfStrings(arrayOfStrings);
}
public void function testAcceptArrayOfNumerics(){
acceptArrayOfNumerics(arrayOfNumerics);
}
public void function testReturnArrayOfNumerics(){
returnArrayOfNumerics(arrayOfNumerics);
}
/**
* @mxunit:expectedexception expression
*/
public void function testAcceptArrayOfNumerics_withStrings(){
acceptArrayOfNumerics(arrayOfStrings);
}
/**
* @mxunit:expectedexception expression
*/
public void function testReturnArrayOfNumerics_withStrings(){
returnArrayOfNumerics(arrayOfStrings);
}
public void function testAcceptArrayOfStructs(){
acceptArrayOfStructs(arrayOfStructs);
}
public void function testReturnArrayOfStructs(){
returnArrayOfStructs(arrayOfStructs);
}
}
Where Sample.cfc is as per above, and SubSample.cfc and NotSample.cfc are as follows:
// SubSample.cfc
component extends="Sample" {
}
// NotSample.cfc
component {
}
To summarise the tests, what I've done is:
- for the functions expecting/returning a Sample array, passed in arrays of Samples, SubSamples, NotSamples, strings. The latter two are expected to error, and do;
- for the functions expecting a string array, just tested with a string array
- for the functions expecting a numeric array, tested with both a numeric array and a string array (the latter ones - correctly - error)
- for the functions expecting a struct array, tested just with a struct array
So the following tests fail:
- passing an array of strings to a function expecting... an array of strings;
- same with the function expecting a numeric array, it fails when it correctly receives an array of numerics;
- same with structs.
Update:
As Rory observes in his comment below: this has all been fixed in Lucee. Nice one.This is a handy feature, but it's incomplete. I've gotta go do some work now, but I'll check if there's a bug report for this, and raise one if not. And I will cross-reference back here either way. I'll also check to see if there's a ticket to implement this in ColdFusion, and raise / cross-reference accordingly.
That's it.
--
Adam