REBOL/Core Users Guide

Changes For Version 2.5.0

Send comments and corrections to Feedback


Table of Contents

1. File Modes
      1.1. Getting lists of applicable modes
      1.2. Modes Available
            1.2.1. File-modes
            1.2.2. Port-modes
            1.2.3. Network-modes
      1.3. Using file forks
      1.4. Finding all available forks
2. Files and Ports
3. Network Protocols
4. Data Series
      4.1. Sort Function
            4.1.1. Terminology
            4.1.2. Arguments
            4.1.3. Comparators
            4.1.4. Comparison dialect
            4.1.5. Examples
5. Math Related
6. Command Line
7. Mold and Load
      7.1. Load/All
8. Console
9. Control
10. Interpreter
11. Objects
      11.1. Make Object Object
      11.2. Third Object
12. Serial Port Access
      12.1. Specifying a Serial Port
      12.2. Operation
13. Other Changes



1. File Modes

GET-MODES and SET-MODES functions have been added for file and network ports. Two new port actions are introduced:

 get-modesReturn current modes for an open port.
 set-modesChange modes for an open port.

The get-modes function has the following syntax:

get-modes: native [
    {Return mode settings for a port}
    target [file! url! block! port!]
    modes [word! block!]
]
The block being passed in consists of words defining which modes should be queried. Each word corresponds to one mode. get-modes returns a block which contains pairs of mode names and current mode settings.

Example:

>> get-modes someport [direct binary]
== [direct: true binary: false]
indicating that someport is opened in direct and non-binary (text) mode.

Alternatively a single word can be passed in, in which case get-modes returns the value directly, without putting it into a name-value block.

Example:

>> get-modes someport 'binary
== false
As another alternative a name/value-paired block can be passed in, of the same format as the block get-modes returns. In that case the values are ignored.

Example:

>> get-modes someport [direct: none binary: none]
== [direct: true binary: false]
The set-modes function has the following syntax:

set-modes: native [
    {Change mode settings for a port}
    target [file! url! block! port!]
    modes [block!]
]
The block being passed in consists of name-value pairs describing the modes to be changed. A block returned by get-modes can be passed as an argument to set-modes. set-modes returns the port that was passed as an argument.

Example:

>> set-modes someport [direct: false binary: false]
The mode block accepted by set-modes is actually an object-style initialization block and allows multiple names to reference the same value.

Example:

>> set-modes someport [direct: binary: false]


1.1. Getting lists of applicable modes

get-modes supports a few "special" modes, which do not return mode settings for a specific port, but rather a set of modes that is applicable for a file (or directory, socket etc.). These are "file-modes", "copy-modes", "network-modes" and "port-modes". If any of these modes are specified in a get-modes request then the response contains a block of matching modes which are available on the current filesystem.

>> get-modes somefileordir 'port-modes
== [direct binary lines no-wait (...a few more...) ]

>> get-modes somefileordir 'file-modes
== [file-note creation-date archived script (...a few more...) ]

>> get-modes someudpsocket 'network-modes
== [broadcast multicast-groups type-of-service]
The above example is for an Amiga. Note that the mode block returned by any of these special requests is identical for all files and directories within a filesystem (and all sockets within a scheme), i.e. it varies per platform and possibly per filesystem and scheme, but not per file or socket. The purpose of this feature is only to provide a mechanism to obtain a list of supported modes, not to obtain the actual mode settings. To obtain the actual mode settings for a port the returned block has to be used in another call to get-modes:

>> get-modes somefileordir get-modes somefileordir 'file-modes
== [file-note: "cool graphics" creation-date: 1-Jan-2000 archived: true script: false]
The difference between "file-modes" and "copy-modes" is:

 file-modesReturn all modes of the underlying data (typically a file), regardless of how it was opened.
 copy-modesSame as file-modes, but only return those modes which are safe to copy, i.e. which can (and should) be included in a set-modes call when creating a new file, in order to create an exact clone of an existing file. If a platform provides file properties which are not safe to copy or which necessarily vary on copied files (e.g. Unix inodes) then those modes would show up in the block returned by file-modes, but not by copy-modes.

Copying all file properties from file1 to file2 can be done with the following call:

>> set-modes file2 get-modes file1 get-modes file1 'copy-modes


1.2. Modes Available


1.2.1. File-modes

Platforms which only support a single file date export it via modification-date. Similarly, platforms which do not support multi-user file access modes make the file access modes available via owner-read/write/delete/execute.


1.2.2. Port-modes


1.2.3. Network-modes


1.3. Using file forks

The /custom refinement to read, open and write allows access to different forks of a file (currently useful for MacOS only).

open/custom %myfile [fork "name"] ; Specify which fork to open.
The specified fork name defines which fork to open:

If no fork is specified (no fork specifier in the custom block or none is passed instead of "name"), then for non-Mac platforms the file is opened normally. For Mac the data fork is opened. If the /new refinement is used then the file size is reset to zero bytes. For Mac this means that all forks are reset to zero bytes. (Note: this behavior has changed from Core 2.3. Previously open/new on Macintosh would only reset the size of the data fork, and there was no way to reset the size of the resource fork.)

If a fork is specified by name then that fork is opened. If the /new refinement is used then the size of only that fork is reset to zero bytes. If the fork does not exist (and, for write access, cannot be created) on the current filesystem then an error is thrown.

Non-Mac platforms only have a single fork named "data". Mac platforms have two forks, named "data" and "resource".


1.4. Finding all available forks

This is done using the mode mechanism, in a way similar to finding all supported modes.

>> get-modes somefile 'forks
== ["data" "resource"]
Example above on Mac. For all other platforms only ["data"] would be returned.



2. Files and Ports



3. Network Protocols



4. Data Series

minimum-of reduce [pi .099 10 * 100]
== [0.099 1000]   

maximum-of reduce [pi .099 10 * 100]
== [1000]


4.1. Sort Function

Several changes and additions have been made to SORT to add functionality, including reverse sorting, hierarchical sorting (sorting on more than one field), sorting of only part of a series, stable sorting (items that are "equal" are not swapped during sorting), and easier specification of sort criteria (without the need for a custom comparator function). The new SORT function is fully backward-compatible.


4.1.1. Terminology

 RecordA single logical item in the series to sort. Usually a character if the series to sort is a string, or a value if the series to sort is a block. If the /skip refinement is used then a record consists of multiple, consecutive elements in the series.
 FieldA part of a record. With the /skip refinement and a skip length of n a field is one of n elements in the record. If the /skip refinement is not used and the series to sort is a block which contains sub-blocks, then a field is one item of a sub-block (NOT the complete sub-block). This allows field-wise sorting of blocked records. In all other cases a field is identical to a record (i.e. each record has exactly one field).
 Field offsetAn integer specifying the offset of a field within a record. For a record consisting of n fields a field offset can be between 1 and n.


4.1.2. Arguments

In addition to the series to sort, the new sort action accepts the following refinements. New behavior is marked with [NEW].

 /caseSort case-sensitive. This only has an effect for fields of type string or character.
 /skip sizeTreat series as records of fixed size. size is of type integer.
 /allUsed in combination with the /skip refinement. [NEW] By default only a single field in a record is used for comparison. If the /all refinement is used then all fields in a record are used for comparison.
 /compare comparatorSpecify a custom comparator. This can be a field offset (type integer [NEW]), a comparator function, or a comparator block [NEW]. See below.
 /reverseSort in reverse. [NEW]
 /part sizeSort only part of a series. (Similar to the use of the /part refinement in copy or change [NEW]).


4.1.3. Comparators

Sorting is performed by comparing and swapping elements, i.e. comparators define the sort order. The following comparators are supported:


4.1.4. Comparison dialect

The following items can appear in a comparison block:

 field offset (integer)Specifies the offset of the next field to compare. Fields are compared in the order specified.
 reverse (word)Sets the comparison for all subsequently specified fields to reverse.
 forward (word)Sets the comparison for all subsequently specified fields to forward (opposite of reverse).
 case (word)Makes the comparison for all subsequently specified fields case-sensitive.
 no-case (word)Makes the comparison for all subsequently specified fields case-insensitive (opposite of case).
 to (word) field offset (integer)Specifies a range of fields to compare, e.g. [1 to 5] compares fields one to five.

With comparison blocks the /all, /case and /reverse refinements slightly change their behaviors: /all is equivalent to adding "to max-field" to the end of the comparison block, i.e. when the end of the comparison block is reached comparison continues until the end of the record is reached. /case specifies that the default case mode (until a case or no-case word is reached) is case-sensitive. Otherwise it is case-insensitive. /reverse reverses the resulting list as a whole, and is independent of the reverse/forward words in the comparison block.


4.1.5. Examples

>> a: [10 "Smith" "Larry" 20 "Smith" "Joe" 80 "Brown" "Harry" 50 "Wood" "Jim"]

>> sort/skip a 3     ; sorts on the first field (number)

== [10 "Smith" "Larry" 20 "Smith" "Joe" 50 "Wood" "Jim" 80 "Brown" "Harry"]

>> sort/skip/compare a 3 2     ; sorts on the second field (last name)

== [80 "Brown" "Harry" 10 "Smith" "Larry" 20 "Smith" "Joe" 50 "Wood" "Jim"]

>> sort/skip/compare/all a 3 2     ; sorts on the second field and following fields (last name and first name)

== [80 "Brown" "Harry" 20 "Smith" "Joe" 10 "Smith" "Larry" 50 "Wood" "Jim"]

>> sort/skip/reverse a 3     ; sorts on the first field (number), in reverse

== [80 "Brown" "Harry" 50 "Wood" "Jim" 20 "Smith" "Joe" 10 "Smith" "Larry"]

>> sort/skip/compare a 3 [2 reverse 3]     ; sorts on the last name forward, and the first name in reverse

== [80 "Brown" "Harry" 10 "Smith" "Larry" 20 "Smith" "Joe" 50 "Wood" "Jim"]



5. Math Related



6. Command Line



7. Mold and Load


7.1. Load/All

Added /all refinement to LOAD. LOAD/all of a script does not evaluate the REBOL header. LOAD/all always returns a block.

Load function refinement precedence:

Evaluate  Returns  
Header?   (pseudo example)
-----------------------------------------------------------------------------
load                   yes  header-obj [rest of script]
load/next              no   [first-val { rest of script }]
load/next/header       yes  [header-obj {rest of script}]
load/header            yes  [header-obj rest of script]
load/all               no   [all of script as data]
load/next/all          no   [first-val { rest of script }]
load/header/all        yes  [header-obj rest of script]
load/next/header/all   yes  [header-obj {rest of script}]
The ALL refinement will be ignored when other refinements are present. Previous table shows the current behavior of the various refinement combinations with LOAD.



8. Console



9. Control



10. Interpreter



11. Objects


11.1. Make Object Object

You can now make an object out of two other objects, a "template object" and a "spec object". When making a new object out of two other objects, the bindings of words coming only from the "spec object" will be maintained, words shared by both the template object and the spec object will take their values from the spec object. This will cause some differences in behavior because the block spec approach is lexical and the object spec approach is definitional.


11.2. Third Object

You can use THIRD on the object to get back a block of set-word value pairs from the object:

z: make object! [a: 99 b: does [a + 1]]
t: third z
== [a: 99 b: func [][a + 1]]
The block returned from THIRD on an object is like an object spec block, however the set-words are bound to their object. This block is like a snapshot of the object's values at that time. You can also use the returned block to set values in the object:

set first t 199
z/b
== 200



12. Serial Port Access

This specification describes the creation and operation of serial communication ports within REBOL. Serial ports were supported in version 2.3 but were not documented.


12.1. Specifying a Serial Port

Serial ports are created in the same manner as other ports within REBOL. The scheme name for serial ports is "serial:". The specification of a serial port may include the device number, the communication speed, the number of data bits, the parity and number of stop bits. The specification information can be specified directly by setting the appropriate fields within the port specification object or by creating a URL which contains the same information. Any field not specified will be given a default value.

The default serial port settings are:

device: port1
speed: 9600
data-bits: 8
parity: none
stop-bits: 1
URL's are encoded with the different fields separated by slashes. For example,

serial://port1/9600/8/none/1
The order of fields is not significant, as the type of field can be determined by the content.

Within a port specification, the various parameters are stored in the following object fields:

host:           device
speed:          speed
data-bits:      data bits
parity:         parity
stop-bits:      stop bits
The portN specification is an indirect reference to the communication device. It refers to the Nth device defined in the System/ports/serial block. This block is initialized by default depending on the system being used and can be modified in user.r to reflect any local requirements.

For example, on Windows the block might be defined as:

System/ports/serial: [ com1 com2 ]
or if COM1 is being used by the mouse, it might just be:

System/ports/serial: [ com2 ]
On unix-style systems, the block might be defined as:

System/ports/serial: [ ttyS0 ttyS1 ]
or if the first device should correspond to COM2:

System/ports/serial: [ ttyS1 ttyS0 ]
Thus, the ports can be specified in a machine indpendent manner while the machine specific definition can be controlled using the serial definition block in System/ports/serial.


12.2. Operation

Serial ports are always opened as direct ports in much the same way as console and network ports. They may be opened as either /STRING or /BINARY with the default being /STRING. They are opened by default as asynchronous, but may be made synchronous by using the /WAIT refinement. When operating asynchronously, any attempts to copy data from the port will return NONE if no data is present. When operating synchronously, the copy will block until data is available.

Data can be written to the port using the INSERT native. Data can be read from the port using the PICK, FIRST or COPY natives with the usual ramifications. As usual with direct ports, the REMOVE, CLEAR, CHANGE and FIND functions are not supported.

The UPDATE function can be used to change port parameters. For example, to change the speed after an initial connection has been established, you could just do:

ser-port: open serial://9600
ser-port/speed: 2400
update ser-port
Changing the device number or the System/ports/serial and calling UPDATE will have no effect. Once the port has been opened with a particular device, the device can't be changed.

There are two additional port fields that can't be set with a URL, but can be set in a port specification block or by manually changing them. The RTS-CTS field specifies whether hardware handshaking should be used on the port. The default is ON. To change the default, do:

ser-port/rts-cts: off
update ser-port
A timeout value can be specified by modifying the timeout field in the port structure. The timeout value only applies to serial ports that are opened with the /wait refinement. When the timeout expires, a serial port timeout error will be generated. To set the timeout value do:

ser-port/timeout: 10        ; 10 second timeout
Serial ports work properly with the WAIT native.



13. Other Changes