dutchlab
dutchlab

Reputation: 590

Coldfusion Structinsert is overwriting the orignal inserted values

I have the following code.

<cfset x = StructNew()>
<cfset y = StructNew()>

<cfset y.name = "1">
<cfset y.id = "2">

<cfset structInsert(x,"item1",y)>

<cfdump var="#x#">

This outputs the following, which I expect.

struct
item1 struct
      name  1
      id    2

Then I add this code to insert another set of data.

<cfset y.name = "3">
<cfset y.id = "4">

<cfset structInsert(x,"item2",y)>

<cfdump var="#x#">

This outputs the following.

struct
item1 struct
      name  3
      id    4
item2 struct
      name  3
      id    4

Why did the item1 data change?

Upvotes: 3

Views: 430

Answers (1)

SOS
SOS

Reputation: 6550

Technically, structInsert isn't overwriting the values - you are - when you do this:

 <cfset y.name = "3">
 <cfset y.id = "4">

 <!--- show values before structInsert --->
 <cfdump var="#x#">

(Notice the dump shows the item1 data has already changed, even before calling structureInsert again?)

The reason is that structures are passed by reference. Meaning x.item1 is only a pointer to the y structure, not an independent copy. So when the code updates the values of y.name and y.id, those changes are automatically reflected in x.item1 as well.

If you want the y structure to be completely independent, either create a new structure first (or use duplicate() to make a deep copy).

<cfset y = structNew()>
<cfset y.name = "3">
<cfset y.id = "4">

Having said that, unless there's a specific reason for using structInsert(), using structure or dot notation is more standard these days:

 <cfset x.item1 = y> ... or
 <cfset x["item1"] = y>

Also, you could reduce the code a LOT by using the shortcut syntax {} for creating and/or populating structures. Here's the entire example in one line:

<cfset x = { "item1": {"name": "1", "id": "2"}
        , "item2": {"name": "3", "id": "4"}
       }>

... or if you needed to append structures individually, use:

<cfset x = {}>
<cfset x["item1"] = {"name": "1", "id": "2"}>
<cfset x["item2"] = {"name": "3", "id": "4"}>

Upvotes: 6

Related Questions