I’m having an issue with a Coldfusion component that I’m building. Well, I’m not really sure if it’s a problem or how things are supposed work, but it seems strange. First, I set up arguments for the init function of my component and invoke the component. But if I change one of the arguments after I invoke, it also changes the values held in the component. Is this correct?
I’m not sure if I’m explaining this very well. Here’s some pseudo-code:
<cfset fruit = [] />
<cfset fruit[1] = {
id = 1,
name = "apple"
} />
<cfset fruit[2] = {
id = 2,
name = "orange"
} />
<cfset args = {
title = "Fruit",
data = fruit
} />
<cfinvoke component="test" method="init" returnvariable="test" argumentcollection=#args# />
<cfset fruit[2].name = "banana" />
The init function stores the title and data arguments in the component’s variables scope.
Now, if I output the data from the test object, I get apple and banana. But I was expecting the component to retain the data that it received during the invoke.
Let me know if I need to clarify anything. Thanks for any help!
Yes, that is how your current code is supposed to work. Whether that is how you want it to behave is a different question ..
Most complex objects (structures, components, etectera) are passed by reference. Meaning you are essentially just storing a pointer to the object, not the actual values. So you will always see any changes made to the underlying object. That is why the output from
testchanges.Arrays are an exception. They are usually (though not always) passed by value. Meaning you have an independent copy that will not reflect any changes made to the original object.
Your example is interesting because it contains both. Changes to your nested structures (
name=orange=>name=banana) are visible in the component because the structures are passed by reference. But the parent array is not. So you could clearfruitand it would have no effect on the component.Example:
Test:
Right. That is to be expected because structures are passed by reference. If you want the component to maintain a independent copy, you need to
duplicate()(ie deep copy) thedataelement insideinit().