[EMAIL PROTECTED] wrote:
> 
>     test: func [input [block!]] [
>       localvar: ""
>       foreach item input [ localvar: append localvar to-string item  ]
>       return localvar
>     ]
> 
>     test2: func [input [block!]] [
>       localvar: make string! 0
>       foreach item input [ localvar: append localvar to-string item ]
>       return localvar
>     ]
> 

Two observations:

1)  In both test and test2, the variable localvar is NOT local.
    You would need to modify your function definitions to begin

        test: func [input [block!] /local localvar] [ ;... etc.

    or

        test: function [input [block!]] [localvar] [ ;... etc.

2)  Ah, yes!  The old string-literals-aren't-what-I-thought gotcha!

    Literal strings in REBOL source evaluate to themselves, as
    opposed to being compiled into instructions to create a string
    with the specified content.

    The body of test is a block, whose first elements are INITIALLY
    a set-word for 'localvar and a string of length zero.  (Feel free
    to insert the phrase "references to" if you're used to working
    with pointer-based data structures.)

    Invoking test makes 'localvar refer to the string in the second
    position, which is then modified by the loop.  THIS MEANS THAT
    THE MODIFICATIONS ARE ACTUALLY AFFECTING THE SECOND ELEMENT OF
    THE BODY OF test!  That means that a subsequent use just keeps
    appending data to the same string.

    In test2, 'localvar is set to refer to a string that is freshly
    created (and initially empty) on every invocation.  A subsequent
    use of test2, therefore, begins by creating a new string -- just
    as the code says.

    This behavior of string literals can be demonstrated by

    >> demo: [weeds: "They"  append weeds " grow & ..."  print weeds]
    == [weeds: "They" append weeds " grow & ..." print weeds]
    >> do demo
    They grow & ...
    >> do demo
    They grow & ... grow & ...
    >> do demo
    They grow & ... grow & ... grow & ...
    >> demo
    == [weeds: "They grow & ... grow & ... grow & ..." append weeds
    " grow & ..." print weeds]
    >>

>
> If it's a feature what's the rule?
>

The rule of thumb is to initialize strings (at least the ones your
code will subsequently modify) with one of these

    stringvar: make string! initialsize
    stringvar: copy ""
    stringvar: copy "initial value"

instead of with

    stringvar: "blah, blah, blah, etc."

Likewise, initialize blocks (or at least the ones your code will
subsequently modify) with one of these

    blockvar: make block! initialsize
    blockvar: copy []
    blockvar: copy ["initial" "values" "go" "here"]

instead of with

    blockvar: ["blah" "blah" "blah" "etc..."]

This rule of thumb applies to all series! types.

Hope this helps!

-jn-

Reply via email to