Andreas
Andreas

Reputation: 53

velocity foreach loop - iterated array gets updated without being used in an assignment

I faced a very strange behaviour in the foreach loop of the following velocity template:

<html>
<body>
<table>

#set( $arrayOfArray = [[1]] )
#set( $new_arrOfArray = [] )
#set( $new_arr = [] )
                        <tr><td>Line 9</td><td>arrayOfArray: $arrayOfArray</td></tr>
#foreach ($arr in $arrayOfArray)
                        <tr><td>Line 11</td><td>arrayOfArray: $arrayOfArray</td></tr>
    #set( $new_arr = $arr )
                        <tr><td>Line 13</td><td>arrayOfArray: $arrayOfArray</td></tr>
    #if ($new_arr.add([ true ])) #end
                        <tr><td>Line 15</td><td>arrayOfArray: $arrayOfArray</td></tr>
    #if ($new_arr.add([5,6])) #end
                        <tr><td>Line 17</td><td>arrayOfArray: $arrayOfArray</td></tr>
    #if ($new_arrOfArray.add($new_arr)) #end
                        <tr><td>Line 19</td><td>arrayOfArray: $arrayOfArray</td></tr>
#end
                        <tr><td>Line 21</td><td>arrayOfArray: $arrayOfArray</td></tr>

</table>
</body>
</html>

As you can see I'm looping through an array of array (for the sake of simplicity I just put a single array into $arrayOfArray in this example, but real life is of course more complex).
As you can also see from the code I do not manipulate the variable $arrayOfArray at all. However, the code generates the following output:

Line 9 arrayOfArray: [[1]]
Line 11 arrayOfArray: [[1]]
Line 13 arrayOfArray: [[1]]
Line 15 arrayOfArray: [[1, [true]]]
Line 17 arrayOfArray: [[1, [true], [5, 6]]]
Line 19 arrayOfArray: [[1, [true], [5, 6]]]
Line 21 arrayOfArray: [[1, [true], [5, 6]]]

So, it seems whenever I add a new array element to $new_arr the variable $arrayOfArray gets also updated.
Is anyone able to explain this behaviour??
Any help highly appreciated.

Andreas

Upvotes: 4

Views: 444

Answers (2)

David Vonka
David Vonka

Reputation: 535

I'm a bit uncertain what you need to do. Would cloning help ? Replacing

#set( $new_arr = $arr )

by

#set( $new_arr = $arr.clone() )

will keep your $arrayOfArray untouched, while the $new_arrOfArray will be [[1, [true], [5, 6]]] at the end.

But maybe I'm missing some point here ...

Upvotes: 1

vzwick
vzwick

Reputation: 11044

By #set( $new_arr = $arr ) you are setting $new_arr to be a reference to $arr.

$arr, in turn, is a reference to $arrayOfArray at a certain index.

When calling new_arr.add(), you're thereby calling $arrayOfArray[$someIndex].add() by reference.

Upvotes: 0

Related Questions