Home   Archive   Permalink



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