Search code examples
loopsuser-interfacerebolred-lang

Variable value in foreach of Red language


I am using following code to add multiple GUI elements to a view via a foreach loop:

myRange: function [n][  ; to produce a vector of [1 2 3 4... n]
  vv: make vector! n 
  i: 1
  foreach j vv [
    vv/:i: i
    i: i + 1
    if i > n [break]]
  vv ]

view collect[ 
    foreach i myRange 10 [  
        print append "i in loop: " i
        keep [ t: text ]  keep append "message number: " i
        keep [field "entry"     button "Click" [t/text: "clicked"] return]
            ] ]

All GUI elements are being produced. But the code append "message number: " i is showing value of i to be 12345678910 in all text elements and not 1, 2, 3... 10 for different text elements.

Also, print append... statement is producing following output:

i in loop: 1
i in loop: 12
i in loop: 123
i in loop: 1234
i in loop: 12345
i in loop: 123456
i in loop: 1234567
i in loop: 12345678
i in loop: 123456789
i in loop: 12345678910

Moreover, clicking any button changes text of only the last added text element.

Where is the problem and how can it be solved? Thanks for your help.


Edit: It seems the language is converting my code from:

for i 1 10 1 [  
   print append "i in loop: " i  ]

to:

a_variable: "i in loop"
for i 1 10 1 [  
   print append a_variable i  ]

Which is not what I and (I think) most users want. In most languages a string "i in loop" will be taken as a constant and not converted to a variable since user has not specified it so. IMHO it will be easier for users of other languages to come here if such basic conventions are not altered.


Solution

  • Whenever you see something like this, it means you failed to create a new series and are reusing an existing series.

    To get around that you need to create a new series with copy

    Eg.

    print append copy "i in loop: " i
    

    Rebol3/ren-c no longer has this problem because source code is immutable and so you will get an error message with such code.