Hello, I don't understand the following behavior:
scheme@(guile-user)> (use-modules (oop goops)) scheme@(guile-user)> (define-class <xyzzy> () (gob #:accessor gob #:init-keyword #:gob)) scheme@(guile-user)> (define a (make <xyzzy> #:gob '(foo))) scheme@(guile-user)> (define b (deep-clone a)) scheme@(guile-user)> (append! (gob b) '(bar)) $1 = (foo bar) scheme@(guile-user)> (gob a) $2 = (foo bar) Why does append! also modify the list in object a? I was under the impression that deep-clone allocates new memory for all slots in b. And if append! clobbers the source memory, why does using set! on the accessor work without overwriting the source memory? scheme@(guile-user)> (define a (make <xyzzy> #:gob '(foo))) scheme@(guile-user)> (define b (deep-clone a)) scheme@(guile-user)> (set! (gob b) (append (gob b) '(bar))) $3 = (foo bar) scheme@(guile-user)> (gob a) $4 = (foo) I guess in this latter case, the call to append definitely allocates new memory for the list and sets the slot to point to the new memory. Isn't that what was supposed to happen with the deep-clone, too? Or is deep-clone just cloning the pointer to the original list's memory without allocating new memory and copying the data to it? The manual says "‘append’ doesn’t modify the given lists, but the return may share structure with the final OBJ." That implies to me that the second method is still unsafe: if I'm actually appending a list stored in some variable that I might be referencing later, modifying (gob b) might end up changing the list bound to that variable. So, what's the best way to do this? Skip the deep-clone, make a new instance of the object from scratch (obviously, the real world example I have in mind is slightly more complicated than the case above), and use append!? Thanks, -- -brandon
