rebol document

Chapter 7 - Block Series

REBOL/Core Users Guide
Main Table of Contents
Send Us Feedback


1. Blocks of Blocks
2. Paths for Nested Blocks
3. Arrays
3.1 Creating Arrays
3.2 Initial Values
4. Composing Blocks

1. Blocks of Blocks

When a block appears as a value within another block, it counts as a single value regardless of how many values it contains. For example:

values: [
    "new" [1 2]
    %file1.txt ["one" ["two" %file2.txt]]
probe values
["new" [1 2] %file1.txt ["one" ["two" %file2.txt]]]

The length? of values is four. The second and fourth values are counted as single values:

print length? values

The block values within the values block can be used as a block as well. In the following examples, second is used to extract the second value from values.

To print the block, type:

probe second values
[1 2]

To get the length of the block, type:

print length? second values

To print the data type of the block, type:

print type? second values

In the same way, series operations can be performed on other types of series values in blocks. In the following examples, pick is used to extract %file1.txt from values.

To look at the value, type:

probe pick values 3

To get the length of the value:

print length? pick values 3

to see the data type of the value:

print type? pick values 3

2. Paths for Nested Blocks

The path notation is useful for nested blocks.

The fourth value in values is a block containing another block. The following examples use a path to get information about this value.

To look at nested values, type:

probe values/4
["one" ["two" %file2.txt]]
probe values/4/2
["two" %file2.txt]

To get the lengths of nested values, type:

print length? values/4
print length? values/4/2

To see what the data type of a nested value, type:

print type? values/4
print type? values/4/2

The two series values in the fourth value's block can also be accessed.

To look at the values, type:

probe values/4/2/1
probe values/4/2/2

To get the lengths of the values:

print length? values/4/2/1
print length? values/4/2/2

To see what data type the values are:

print type? values/4/2/1
print type? values/4/2/2

To modify the values:

change (next values/4/2/1) "o"
probe values/4/2/1
change/part (next find values/4/2/2 ".") "r" 3
probe values/4/2/2

The above examples illustrate REBOL's ability to operate on values nested inside blocks. Note that in the last series of examples, change is used to modify a string and file series three layers deep in values. Printing out the values block produces:

probe values
["new" [1 2] %file1.txt ["one" ["too" %file2.r]]]

3. Arrays

Blocks are used for arrays.

An example of a statically defined two dimensional array is:

arr: [
    [1   2   3  ]
    [a   b   c  ]
    [$10 $20 $30]

You can obtain the values of an array with the series extraction functions:

probe first arr
[1 2 3]
probe pick arr 3
[$10.00 $20.00 $30.00]
probe first first arr

You can also use paths to obtain values from the array:

probe arr/1
[1 2 3]
probe arr/3
[$10.00 $20.00 $30.00]
probe arr/3/2

Paths can also be used to change the values in an array:

arr/1/2: 20

probe arr/1 == [1 20 3]

arr/3/2: arr/3/1 + arr/3/3

probe arr/3/2 == $40.00

3.1 Creating Arrays

The array function creates arrays dynamically. The function takes an argument that is either an integer or a block of integers and returns a block that is the array. By default, the cells of an array are initialized to none. To initialize array cells to some other value, use the /initial refinement explained in the next section.

When array is supplied with a single integer, a one-dimensional array of that size is returned:

arr: array 5
probe arr
[none none none none none]

When a block of integers is provided, the array has multiple dimensions. Each integer provides the size of the corresponding dimension.

Here is an example of a two dimensional array that has six cells, two rows of three columns:

arr: array [2 3]
probe arr
[[none none none] [none none none]]

This can be made into a three dimensional array by adding another integer to the block:

arr: array [2 3 2]
foreach lst arr [probe lst]
[[none none] [none none] [none none]]
[[none none] [none none] [none none]]

The block of integers that is passed to array can be as big as your memory will support.

3.2 Initial Values

To initialize the cells of an array to a value other than none, use the /initial refinement. This refinement takes one argument: the initial value. Here are some examples:

arr: array/initial 5 0
probe arr
[0 0 0 0 0]
arr: array/initial [2 3] 0
probe arr
[[0 0 0] [0 0 0]]
arr: array/initial 3 "a"
probe arr
["a" "a" "a"]
arr: array/initial [3 2] 'word
probe arr
[[word word] [word word] [word word]]
arr: array/initial [3 2 1] 11:11
probe arr
[[[11:11] [11:11]] [[11:11] [11:11]] [[11:11] [11:11]]]

4. Composing Blocks

The compose function is handy for creating blocks from dynamic values. It can be used for creating both data and code.

The compose function takes a block as an argument and returns a block that has each value in the argument block. Values in parentheses are evaluated before the block is returned. For example:

probe compose [1 2 (3 + 4)]
[1 2 7]
probe compose ["The time is" (now/time)]
["The time is" 10:32:45]

If the values in parentheses return a block, that block's individual values are used:

probe compose [a b ([c d])]
[a b c d]

To prevent this, you need to enclose the result in an extra block:

probe compose [a b ([[c d]])]
[a b [c d]]

An empty block inserts nothing:

probe compose [a b ([]) c d]
[a b c d]

When compose is given a block that contains sub-blocks, the sub-blocks are not evaluated, even if they contain parentheses:

probe compose [a b [c (d e)]]
[a b [c (d e)]]

If you would like the sub-blocks to be evaluated, use the /deep refinement. The /deep refinement causes all parentheses to be evaluated, regardless of where they are:

probe compose/deep [a b [c (d e)]]
[a b [c d e]]

Updated 8-Apr-2005 - Copyright REBOL Technologies - Formatted with MakeDoc2 Documents Manual Dictionary Library Feedback