Array incompat

11 views
Skip to first unread message

Adam Cameron

unread,
Oct 16, 2010, 12:30:31 PM10/16/10
to Railo
G'day
This is an inconsistency with CF that Railo shares with BD. I'm not
sure why my tests show this up on Railo but not BD though... I need to
look at that... hmmm...

Anyway, some code:

<!--- Numbers.cfc --->
<cfcomponent>

<cfset variables.aNumbers = listToArray("tahi,rua,toru")>

<cffunction name="getNumbers" returntype="array">
<cfreturn variables.aNumbers>
</cffunction>

</cfcomponent>

<!--- caller.cfm --->
<cfset o = createObject("component", "Numbers")>

<cfset aNumbers1 = o.getNumbers()>
<cfset arrayAppend(aNumbers1, "wha")>
<cfdump var="#aNumbers1#">

<cfset aNumbers2 = o.getNumbers()>
<cfset arrayAppend(aNumbers2, "wha")>
<cfdump var="#aNumbers2#">

Now, because - I guess - CF copies the array when it's assigned to a
new variable, I just end up with "tahi, rua, toru, wha" in the second
dump (which is what I'd expect). On BD (Open & .NET), and Railo, I
guess it's just referencing the one array throughout, so I get "tahi,
rua, toru, wha, wha".

I realise the way CF handles arrays is a bit of an idiosyncracy cf
other complex data types, but given the precedent is set, should not
the other engines follow suit?

I'll cross-post this on the OpenBD forum too, I think.

--
Adam

Sean Corfield

unread,
Oct 16, 2010, 12:52:52 PM10/16/10
to ra...@googlegroups.com
ACF's behavior runs counter to pretty much every other language I've
worked with (shallow copying arrays on assignment) and it's
inefficient to boot. I believe Railo offers an Administrator option to
change to the less efficient / more compatible behavior but it's not
something that will get changed in the core engine.

Note that the following does *not* cause a copy and *will* append to
the array in ACF:

<cfset arrayAppend(o.getNumbers(), "wha")>
<cfdump var="#aNumbers1#">

<cfset arrayAppend(o.getNumbers(), "wha")>
<cfdump var="#aNumbers2#">

Sean

--
Sean A Corfield -- (904) 302-SEAN
Railo Technologies, Inc. -- http://getrailo.com/
An Architect's View -- http://corfield.org/

"If you're not annoying somebody, you're not really alive."
-- Margaret Atwood

Andrea Campolonghi

unread,
Oct 16, 2010, 12:50:11 PM10/16/10
to ra...@googlegroups.com
Cameron,

ACF pass arrays by value while Railo and ODB pass them by reference.
This is a known difference between the engines that in any case will not be resolved ( at least from Railo side ....as far as I know ) 
I think this acf design comes from very far ( cf5 ? ) and I think Adobe will keep this strange behaviour to keep code retrocompatibility.

Andrea 

2010/10/16 Adam Cameron <camero...@gmail.com>



--
Andrea Campolonghi
and...@getrailo.org

Adam Cameron

unread,
Oct 16, 2010, 1:08:52 PM10/16/10
to Railo
Hi Sean
Speaking of idiosyncracies, it's "interesting" that Railo chooses to
emulate how *other languages* handle arrays in this regard, but not to
emulate the language it itself is an emulation of.

But I agree it's a more sensible approach, and it's no prob - in this
case - for me to change my code to accommodate it.

I still can't work out why my unit test which fails on this on Railo
does NOT fail on either flavour of BD, but the factored-down repro
case fails on those two as well. I tried to refactor my repro case to
be closer to the production code, but still could not get differing
behaviour between Railo & BD, other than in my unit test. There's are
a swag more "moving parts" involved in the production code, obviously,
so I guess I'm not seeing a difference in there somewhere. But it
does look to me that in *some* sort of assignments, BD is copying the
array, not just passing its reference. Odd.

But anyway, the fix - just to duplicate() it before I start monkeying
with it - will work across the board anyhow.

Cheers for the quick response. Got any thoughts about my custom tags
posting from a bit earlier? ;-)

--
Adam

Sean Corfield

unread,
Oct 16, 2010, 3:07:13 PM10/16/10
to ra...@googlegroups.com
On Sat, Oct 16, 2010 at 10:08 AM, Adam Cameron <camero...@gmail.com> wrote:
> Speaking of idiosyncracies, it's "interesting" that Railo chooses to
> emulate how *other languages* handle arrays in this regard, but not to
> emulate the language it itself is an emulation of.

There are some decisions made in the history of CFML that are just
plain weird and shallow-copy-on-assignment of arrays is one of the
stranger ones. Railo's general approach is to take a more intuitive /
more performant approach in those situations but offer a setting for
compatibility.

Transfer ORM is affected by this particular decision and does things
that rely on array copying. That's unfortunate because
pass-by-reference semantics for arrays is much faster and, in most
cases, causes no compatibility problems at all.

> Cheers for the quick response.  Got any thoughts about my custom tags
> posting from a bit earlier? ;-)

I looked at that but had no insight at the time (truth to tell, I'm on
vacation in Los Angeles right now - at a cat show - so I'm not really
"working"). Given my crazy travel situation over the next two weeks, I
may not get to a place where I can set up a test case for your custom
tags to analyze the problem so you may just be better off opening a
ticket in JIRA for Micha to look at...

Michael Offner

unread,
Oct 17, 2010, 3:49:36 AM10/17/10
to ra...@googlegroups.com
We had already hard discussion about this in past. We will not support
this behavior by default, BUT we will add a setting to Railo to enable
this behavior and in addison you can enable this in the code as
follows for a single operation:
<cffunction returnPassBy="value" ...>
<cfargument passBy="value" ...>
</cffunction>

ACF will simple ignore this settings, passby for argument is already
supported, returnpassby will follow soon.

What you of course can do as well (this is war acf does in fact) is
the following.
<cffunction ...>
<cfargument ...>
<cfreturn duplicate(arr)>
</cffunction>

/micha

2010/10/16, Sean Corfield <seanco...@gmail.com>:

Reply all
Reply to author
Forward
0 new messages