On 1/9/2012 10:35 AM, David Harkness wrote:
On Sat, Jan 7, 2012 at 5:01 PM, Tim Behrendsen <tim@xxxxxxxxxxxxxx
<mailto:tim@xxxxxxxxxxxxxx>> wrote:
The first loop is leaving a reference to the final element. But
then the second foreach is doing a straight assignment to the $row
variable, but $row is a reference to the final element. So the
foreach is assigning its iterated value to the final element of
the array, instead of a normal variable.
Exactly, and the fact that it shows "1, 2, 2" in the second loop adds
more confusion, but it makes sense. In the second loop, it assigns the
indexed row value into the third row and displays it. Thus it displays
row 1, row 2, and then ... row 3, but row 3 is the one that keeps
getting overwritten. And in the third iteration, it overwrites the
third row with the third row which currently holds what was in row 2.
The moral is always unset the iterator variable when doing foreach
with a reference, like the manual says. :)
While you can certainly follow the above advice, in my view it's
dangerous to have these two loops a) reuse the same variable name for
a different purpose and b) exist in the same scope. More and more I
find myself dropping the subtle tricks I've learned over the years in
favor of writing code that is as easy to understand as possible. Code
gets read and modified a lot more than it gets written, and all those
tricks just trip up more junior teammates--and often even myself. :)
David
Agreed, in fact, I decided to create a new style naming convention where
"_ref" is always suffixed to variable names that are references, along
with doing the unset, just in case. This goes to show that references
can be a recipe for subtle bugs to creep in, so best to isolate them as
much as possible to their own convention. If the convention is followed,
it should eliminate the possibility of this bug, even if the unset is
left out.
Tim