3

I entered these statement:

let list = [[[0,0],[0,0],0], [[0,0],[0,0],0]]
for [a,b,c] in list
    let c = 5
endfor

And then when I executed echo list, I get

[[[0,0],[0,0],0], [[0,0],[0,0],0]]

I.e. nothing changed at all. Why is this? This seems like an error to me.

Especially because

let list = [[[0,0],[0,0],0], [[0,0],[0,0],0]]
for [a,b,c] in list
    let b[0] = 5
endfor

Does what you would expect it does. What explains this seemingly erratic behavior?

  • 2
    a and b are lists, so they are passed by reference. c is a number, so it's passed by value. Changing list by changing b works by accident, not by design. Relying on this behaviour is asking for segfaults later on. At the very least, the reference counts can be wrong in more complicated expressions. Make sure you understand the difference between lvalues and rvalues before even considering going there. – Sato Katsura Jun 20 '16 at 5:02
7

The problem is that you're deconstructing each list item into [a, b, c]. c is a copy since it's not an object, which would be the case in a lot of other languages.

This is basically what your example does:

let list = [[[0,0],[0,0],0], [[0,0],[0,0],0]]
for item in list
  let c = item[2]
  let c = 5
endfor

This is what you want to do:

let list = [[[0,0],[0,0],0], [[0,0],[0,0],0]]
for item in list
  let item[2] = 5
endfor
  • So to actually write over the third item, you need: let item[2] = 5 – joeytwiddle Jun 20 '16 at 3:49
  • @SatoKatsura are you referring to my answer? The example shows the mistake in hgiesel's reasoning. Not "magically" turning c into a reference. – Tommy A Jun 20 '16 at 5:20
  • Sorry, too much blood in my coffee system. :) – Sato Katsura Jun 20 '16 at 5:38
  • @SatoKatsura No sweat. I clarified the answer with a solution. – Tommy A Jun 20 '16 at 19:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.