Just What Exactly *DOES* structCopy() Do?
This entry is related to the Structure Nesting post from earlier today. I was talking more with Sean about what structCopy() really does. To be honest, I’ve never really used this function. I’ve SEEN it, but that’s about it.
Let’s have a look…
I’m sure you recognize this from the previous post:
<cfscript>
structA = structNew();
structA["structB"] = structNew();
structA["structB"]["employees"] = structNew();
structA["structB"]["employees"]["001"] = structNew();
structA["structB"]["employees"]["001"].fname = “Will”;
structA["structB"]["employees"]["001"].lname = “Tomlinson”;
structA["structB"]["employees"]["001"].age = 38;
</cfscript>
That’s our old nested struct.
Let’s append a new employee to it using Sean’s technique.
<cfscript>
newEmployee = {fname=”Suzy”,lname=”Ormand”,age=50};//Setup a new emp
newNum = 002;//Setup a new number
structA["structB"]["employees"][newNum] = structCopy(newEmployee);
</cfscript>
<cfdump var=”#structA#” label=”StructA”>
Produces this:
What did we do here?
structA["structB"]["employees"][newNum] = structCopy(newEmployee);
We made a copy of our new employee struct. Why would we do this? Well, now structCopy(newEmployee) points to an entirely new struct, NOT the old one. If we change a variable, we know we’re changing it in the old struct, WITHOUT affecting the new copy.
Can we see this in action? Heck yeah!
<cfscript>
newEmployee = {fname=”Suzy”,lname=”Ormand”,age=50};//Setup a new emp
newNum = 002;//Setup a new number
structA["structB"]["employees"][newNum] = structCopy(newEmployee);
newEmployee.fname = “Gertrude”;//Let’s screw with a variable to see what happens
</cfscript>
<cfdump var=”#structA#” label=”StructA”>
Produces this:
Um, there’s no change here. That’s exactly right! We made a copy of our new employee, then stuffed it into the employees struct.
With this line, we changed a variable’s value in the old struct, without affecting the new nested struct!
newEmployee.fname = “Gertrude”;//Let’s screw with a variable to see what happens
Let’s try something else:
<cfscript>
newEmployee = {fname=”Suzy”,lname=”Ormand”,age=50};//Setup a new emp
newNum = 002;//Setup a new number
structA["structB"]["employees"][newNum] = newEmployee;
newEmployee.fname = “Gertrude”;//Let’s screw with a variable to see what happens
</cfscript>
<cfdump var=”#structA#” label=”StructA”>
What did we do here? I eliminated structCopy(), so we could see what happens if you simply refer to the old struct variable “newEmployee”. It works with no problems …. yet!
Now, what happens when we change an employee’s info in the old struct with this line?
newEmployee.fname = “Gertrude”;//Let’s screw with a variable to see what happens
Uh oh! We just changed Suzy’s name to Gertrude! That could get ugly in certain situations. Changing our variable’s value *spilled over* into our newEmployee struct. That’s what we’re trying to avoid, spill over. We want that copied struct to be its own entity, detached from the old struct we copied it from.
I’ll be sticking with Sean’s technique of using structCopy() so I don’t have undesired results.
Hope this clears things up a bit. Thanks to Sean for taking the time to explain this! If I left anything out, or got something wrong, please correct me.
* Update 7-6-08
Charlie Griefer just gave me some good info regarding my examples. Sean also explained the same thing the other day, but it’s a little tricky and takes a little time to grasp.
It boils down to this; if you want a completely new copy of your nested struct, and not have to worry about corrupting its data by changing variable values in your original struct, use duplicate() instead of structcopy(). structCopy() does a shallow copy of your structure, while duplicate is a deep copy.
structCopy() from the docs:
“Returns a “shallow” copy of the structure. All embedded objects are references to the objects in the original structure. The Duplicate function has replaced this function for most purposes.”
What does this mean? If you you structCopy(), then change a variable in one of your original structure’s nested structs, you’re screwed – it changes the value in your copy as well.
Use duplicate() instead, and it wont. This is because duplicate() is an entirely new struct … nested structs included! This new struct is completely independent of the original.
Another point Sean makes is, you don’t *always* want to use duplicate ( A deep copy). For instance, if you’re copying a struct with one level, use structCopy().
Hope this clarifies things a little. If anyone has more info, please share.
Thanks again to Charlie and Sean!
1 comment so far
Leave a reply



[...] on Will Tomlinson’s blog there’s a piece about using structCopy() to create a copy of a struct and a note from Charlie [...]