Strange VID behavior I think
I have finished up a day of head-beating and discovered something strange. I have gotten my program to work, so all is well there, but I would like to understand what is going on here. It seems that if I have a program that gets data from a window and appends it to a block in the program, that block gets altered the next time I type stuff in the window even if I don't explicitly append it to the block. A sample program follows that shows this happening. I am wondering if anyone can explain it. Thank you. R E B O L [ Title: 'Append test' ] ;; -- We want to get data from a window and append it to this block. SOME-OTHER-BLOCK: [] ;; -- This function appends the field from the screen to the block. APPEND-BUTTON: does [ append SOME-OTHER-BLOCK trim get-face MAIN-FIELD1 alert 'OK' ] ;; -- The DEBUG button shows the value of SOME-OTHER-BLOCK ;; -- so you can check it before using the APPEND button. DEBUG-BUTTON: does [ print ['Value of SOME-OTHER BLOCK is: ' SOME-OTHER-BLOCK] ] ;; -- Main window. MAIN-WINDOW: layout [ across label 'Field 1:' MAIN-FIELD1: field 100 return button 'APPEND' [APPEND-BUTTON] button 'DEBUG' [DEBUG-BUTTON] return text 400 '1. Enter something in the field and press APPEND' return text 400 '2. Press DEBUG to see that it has been appended' return text 400 '3. Enter something different and DO NOT press APPEND' return text 400 '4. Press DEBUG and see that SOME-OTHER-BLOCK has changed' return text 400 '5. Press APPEND and DEBUG again to see that append works.' ] view center-face MAIN-WINDOW
posted by: Steven White 18-Mar-2015/15:37:57-7:00
The fix is to use COPY: append SOME-OTHER-BLOCK trim COPY get-face MAIN-FIELD1 Now for the explanation of the problem: GET-FACE of a FIELD simply returns the face/text, as you can see here: ?? get-face print mold get in main-field1/access 'get-face* And TRIM modifies and passes through its argument, as you can see here: s: " abc " trim s s >> "abc" That means the APPEND-BUTTON function is appending instances of the SAME STRING to the block each time; duplicate references to the same string that MAIN-FIELD1/text references. To say it another way: That string started off life with only one reference to it in face/text when the MAIN-FIELD1 face was created. Then APPEND-BUTTON starts appending references to the same string to the block. So, when the face/text (of MAIN-FIELD1 face) string is modified, all those references reflect the change. Strings are series. Understanding how series work is fundamental to rebol, and, with that understanding it becomes clear when it's necessary to copy. It can be helpful for the DEBUG-BUTTON function to print MOLD SOME-OTHER-BLOCK, eg: ?? SOME-OTHER-BLOCK
posted by: Anton Rolls 18-Mar-2015/22:21:14-7:00
Thank you. Interestingly, I sort of knew about the issue from an article by Carl: http://www.rebol.net/cookbook/recipes/0013.html But I didn't understand the full implications of that article when I read it. I am further hindered by my mental paradigm of variables and contents versus words and values. I can see now that I was not appending the CONTENTS of MAIN-FIELD1/text to the block, but only a REFERENCE to MAIN-FIELD1/text.
posted by: Steven White 19-Mar-2015/9:58:36-7:00
|