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.
Rebol and Red reuses series (e.g. strings, blocks) as much as possible if you do not tell them otherwise by initializing anew with
copy
,make
etc. So your issue should go away if you writeAs the other answers suggest, you are only using a single string for your message and would need to be copied.
As to the other concern—you should take a wee look at the code you're generating (as I suggested elsewhere, you can pop a little
PROBE
to examine the output of theCOLLECT
function):As you can see, you're constantly reassigning
t
so that in the end, it only refers to the last face.A few options exist here—most prominent is to generate the name you're assigning the
text
face to. Within yourFOREACH
loop:Note that in order to simplify the block creation, I used this line:
This composes to (in the first instance):
IN
returns the given word ('text
) bound to the given context (the face objectt-1
) which is thenSET
to"clicked"
.UPDATE
This method doesn't even use a word name, just uses a common parent to connect the button to the label:
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.
Rebol3/ren-c no longer has this problem because source code is immutable and so you will get an error message with such code.