Why is this happening

59 views
Skip to first unread message

Dan Vega

unread,
Mar 20, 2011, 3:48:46 PM3/20/11
to coldfu...@googlegroups.com
I have this method below that will get metadata from a component. I am using a bit of hack to push metadata into the object but its there. If I pass an object to this method and dump the contents of constraints right before the return I see the exact value I am hoping for. This is not what is being returned though. The value from the 1st pass through is what ends up getting returned. Any ideas why this is happening/ 

public any function getConstraints(any target,array constraints=[]){
var meta = (isObject(target)) ? getMetaData(target) : getComponentMetadata(target);
if( !isNull(meta.constraints) ){
// this is an array of constraints
for( var x=1; x<=arrayLen(meta.constraints); ++x){
arrayAppend(arguments.constraints,meta.constraints[x]);
}
if( !isNull(meta.extends.constraints) ){
getConstraints(meta.extends.fullname,constraints);
}
}
return constraints;
}

Dennis Clark

unread,
Mar 20, 2011, 4:05:43 PM3/20/11
to coldfu...@googlegroups.com

Arrays are passed by value in CF, so you must bubble up the return value from the recursive call. Use:

constraints = getConstraints(...)

or

return getConstraints(...)

-- Dennis (via phone)

On Mar 21, 2011 6:48 AM, "Dan Vega" <dan...@gmail.com> wrote:

Dan Vega

unread,
Mar 20, 2011, 4:15:41 PM3/20/11
to coldfu...@googlegroups.com
dumb mistake ..thanks Dennis! 

Sean Corfield

unread,
Mar 20, 2011, 5:11:11 PM3/20/11
to coldfu...@googlegroups.com
Or use a struct with numeric keys (structs are passed by reference and
can be more efficient than copying arrays around, depending on how
many elements are in your array).

Note that ACF is alone in this behavior: Railo and OpenBD handle
arrays by reference just like other languages. Something to bear in
mind if you're trying to write portable code.

Also note that technically it is NOT pass by value: arrays are copied
on assignment in ACF - shallow copied. You can see that behavior here:

a = [ 1, 2 ];
function t() { return a; }
b = a; // copy on assignment
arrayAppend( b, 3 ); // does not affect a
c = t(); // copy on assignment
arrayAppend( c, 4 ); // does not affect a
arrayAppend( t(), 5 ); // updates a

The reason is that arrays are _returned_ by reference but are usually
copied on assignment to some other variable. If you use a built-in
function (which does not cause copying on assignment to be triggered),
arrays returned (by reference) from functions will be modified by the
built-in function.

And if you want to verify that it really is a shallow copy, not a deep
copy - i.e., not duplicate() - try:

s = { x = 1 };
a = [ s ];
b = a;
b.y = 2; // modifies s

This weird behavior - and for obvious performance reasons - is why
both Railo and OpenBD chose to go with the more common and more
intuitive behavior of treating arrays as reference types.

Sean

Dennis Clark

unread,
Mar 20, 2011, 8:23:56 PM3/20/11
to coldfu...@googlegroups.com
Thanks for the edification Sean. Next time I'll say "Adobe CF passes arrays by shallow copy and returns them by reference". Simply trying to think of the potential bugs that might ensue from this behaviour in code that operates with deep arrays is giving me a headache.

I'm all for questioning conventional programming language wisdom, but it seems an odd design choice by Adobe to handle arrays in a way that's so different from every other language I know. Some days I wonder whether someone inside Adobe is trying to turn ACF into INTERCAL 2.0 ;)

-- Dennis

--
You received this message because you are subscribed to the Google Groups "Object-Oriented Programming in ColdFusion" group.
To post to this group, send email to coldfu...@googlegroups.com.
To unsubscribe from this group, send email to coldfusionoo...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/coldfusionoo?hl=en.


Sean Corfield

unread,
Mar 20, 2011, 8:34:28 PM3/20/11
to coldfu...@googlegroups.com
On Sun, Mar 20, 2011 at 5:23 PM, Dennis Clark <boom...@gmail.com> wrote:
> Thanks for the edification Sean. Next time I'll say "Adobe CF passes arrays
> by shallow copy and returns them by reference". Simply trying to think of
> the potential bugs that might ensue from this behaviour in code that
> operates with deep arrays is giving me a headache.

Yeah, it's quite the mouthful :(

> I'm all for questioning conventional programming language wisdom, but it
> seems an odd design choice by Adobe to handle arrays in a way that's so
> different from every other language I know.

I suspect it was an accidental implementation choice in the early days
and then the spectre of backward compatibility prevented it ever
getting fixed. There are certainly some odd choices in the language -
lots of inconsistencies and strange omissions - but J.J. and Jeremy
were innovators rather than language designers and things have
improved over the years (arguably). CFML is never going to be a
"well-designed" language, it's always going to be an "organically
grown" language :)
--
Sean A Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/
World Singles, LLC. -- http://worldsingles.com/
Railo Technologies, Inc. -- http://www.getrailo.com/

"Perfection is the enemy of the good."
-- Gustave Flaubert, French realist novelist (1821-1880)

Reply all
Reply to author
Forward
0 new messages