[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-