REBOL 3 Docs Guide Concepts Functions Datatypes Errors
  TOC < Back Next >   Updated: 11-Apr-2009 Edit History  

REBOL 3 Concepts: Series: Making and Copying Series

Pending Revision

This document was written for R2 and has yet to be revised for R3.

Contents

Making a new series

New series are created with the make and copy functions.

Use the make function to create a new series from a series datatype and an initial size. The size is an estimate of the size needed for the series. If the initial size is too small, the series will automatically expand, but at a slight performance cost.

block: make block! 50

string: make string! 10000

list: make list! 128

file: make file! 64

Copying a series

The copy function creates a new series by copying an existing series:

string: copy "Message in a bottle"

new-string: copy string

block: copy [1 2 3 4 5]

new-block: copy block

Copying is also important for use with functions that modify the contents of a series. For instance, if you want to change the case of a string without modifying the original, use the copy:

string: uppercase copy "Message in a bottle"

Partial Copies

The copy function /part refinement takes a single argument, which is either an integer specifying the number of items to copy or a position within the series indicating the last position to copy.

str: "Message in a bottle"
print str
Message in a bottle
print copy/part str find str " "
Message
new-str: copy/part (find str "in") (find str "bottle")
print new-str
in a
blk: [ages [10 12 32] sizes [100 20 30]]
new-blk: copy/part blk 2
probe new-blk
[ages [10 12 32]]

Deep Copies

Many blocks contain other blocks and strings. When such a block is copied, its sub-series are not copied. The sub-series are referred to directly and are the same series data as the original block. If you modify any of these sub-series, you modify them in the original block as well.

The copy/deep refinement forces a copy of all series values within a block:

blk-one: ["abc" [1 2 3]]
probe blk-one
["abc" [1 2 3]]

The next example assigns a normal copy of blk-one to blk-two:

blk-two: copy blk-one
probe blk-one
["abc" [1 2 3]]
probe blk-two
["abc" [1 2 3]]

If either the string or block contained in blk-two is modified, the series values in blk-one are also modified.

append blk-two/1 "DEF"
append blk-two/2 [4 5 6]
probe blk-one
["abcDEF" [1 2 3 4 5 6]]
probe blk-two
["abcDEF" [1 2 3 4 5 6]]

Using copy/deep makes a copy of all series values found in the block:

blk-two: copy/deep blk-one
append blk-two/1 "ghi"
append blk-two/2 [7 8 9]
probe blk-one
["abcDEF" [1 2 3 4 5 6]]
probe blk-two
["abcDEFghi" [1 2 3 4 5 6 7 8 9]]

Initial Copies

When initializing a string or block series, use copy on the value to make is a unique series:

str: copy ""
blk: copy []

Using copy assures that a new series is created for the word every time the word is initialized. Here is an example of why this is important.

print-it: func [/local str] [
    str: ""
    insert str "ha"
    print str
]

print-it
ha
print-it
haha
print-it
hahaha

In this example, because copy wasn't used, the empty string series is modified with every call of print-it. The string series ha is inserted into str each time print-it is called.

Examining the source of the function as it now exists exposes the root of the problem:

source print-it
print-it: func [/local str] [
    str: "hahaha"
    insert str "ha"
    print str
]

Although str is a local variable, its string value is global. To avoid this problem, the function should copy the empty string or use make on the string.

print-it: func [/local str] [
    str: copy ""
    insert str "ha"
    print str
]

print-it
ha
print-it
ha
print-it
ha


  TOC < Back Next > REBOL.com - WIP Wiki Feedback Admin