REBOL
Downloads Products Documents Community

REBOL/Core 2.2 Changes

First Release: October-1999

Back to REBOL Change Logs

Contents

New Features
Fixes
Console
Keyboard Input Sequences
Terminal Output Sequences
Examples
Security Settings
Prior Security Settings
Protect
Function Attributes
New Functions and Refinements
Build-Tag
Reverse
Forever
Difference
Replace
Literal Paths
Resend
Email Paths
Do/next
Load/next
Append/only
Find/last and /reverse

New Features

Here are the new features added to this version since version 2.1.2. Follow links for more information:

Fixes

Here are the fixes made to this version since version 2.1.2.

Console

The REBOL command line console has been completely redesigned for 2.2. The new console now provides "virtual terminal" capability that allows you to perform operations such as cursor movement, cursor addressing, line editing, screen clearing, control key input, and cursor position querying. In addition, on platforms like Windows the console style will be more standard in its appearance and will operate several times faster. The control sequences follow the ANSI standard. These features provide you with all the capability you need to write your own platform-independent terminal programs such as text editors, email clients, or Telnet emulators.

The new console features apply to both input and output. On input, special control keys will be converted to multiple-character escape sequences. On output, multiple-character escape sequences can be used to control the display of text in the console window. Both the input and output sequences begin with an /escape/ character, 27 decimal (1B hex). The next character in the sequence indicates the control keys on input or the terminal control operation on output.

Note that the characters are case-sensitive requiring an upper case character.

Keyboard Input Sequences

The special keys and second character in the sequence are included in the following table:

KEY     ^(1B)[
UP      A
DOWN    B
RIGHT   C
LEFT    D
HOME    1~
INSERT  2~
END     4~
PG UP   5~
PG DN   6~

Terminal Output Sequences

There are several variations in the terminal control output character sequences. Some command codes are preceded by a count sent in ASCII form indicating that the operation is to be performed the specified number of times. The cursor motion command may be preceded by two numbers separated by a semicolon to indicate the row and column position to move to. The cursor command characters (upper case required) are included in the following table:

^(1B)[  Use this escape code prior to the following codes
D       Moves cursor one space left
C       Moves cursor one space right
A       Moves cursor one space up
B       Moves cursor one space down
/ n/ D  Moves cursor /n/ spaces left
/ n/ C  Moves cursor /n/ spaces right
/ n/ A  Moves cursor /n/ spaces up
/ n/ B  Moves cursor /n/ spaces down
/ r/ ; /c/ H    Moves cursor to row /r/, column c
H       Moves cursor to top left corner (home)
P       Deletes one character to the right at current location
/ n/ P  Deletes /n/ characters to the right at current location
@       Inserts one blank space at current location
/ n/ @  Inserts /n/ blank spaces at current location
J       Clears screen and moves cursor to top left corner (home)
K       Clears from current position to end of current line
6n      Places the current cursor position in the input buffer
7n      Places screen dimensions in the input buffer

Top left corner is defined as row 1, column 1

Examples

Moving cursor to the right ten spaces

print "^(1B)[10CHi!"
          Hi!

Moving cursor to the left seven spaces and clearing the remainder of the line

cursor: func [parm [string!]][join "^(1B)[" parm]
print ["How are you" cursor "7D" cursor "K"]
How a

Finding current console dimensions:

cons: open/binary [scheme: 'console]
print cursor "7n" screen-dimensions: next next to-string copy cons
"33;105R"
close cons

The example opens the console, sends a control character to the input buffer and copies the return value, then reads the value (screen-dimensions) that is returned after (next) the control character. It then closes the console. The return is the height and width separated by a semicolon (;) and followed by an R: 33 high x 105 wide. Your console screen dimensions will vary.

Note: Printing a character to the bottom-right corner of some terminals will cause a new line, which will scroll the screen. Others will not. This inconsistency between console terminal types must be considered when writing REBOL scripts intended to be cross-platform.

Security Settings

The secure function has changed with version 2.2. The new function provides much more flexibility in setting and controlling the security features of REBOL. The new function is /not/ backward-compatible with previous versions of REBOL and will require changes to scripts that use the secure native function. The current security settings are returned as a result of calling the secure function.

Security settings use a REBOL dialect, a language within a language. The normal dialect consists of a block of paired values. The /first/ value in the pair specifies what is being secured:

The /second/ value in the pair specifies the level of security. This can be either a security level word or a block of words. The security level words are:

allowallow access with no restrictions (formerly none).
askask permission if any restricted access occurs.
throwthrow an error if any restricted access occurs.
quitquit this REBOL session if any restricted access occurs.

For example, to allow all network access, but to quit on any file access:

secure [
    net allow ;allows any net access
    file quit ;any file access will cause the program to quit
]

If a block is used instead of a security level word, it can contain pairs of security levels and access types. This lets you specify a greater level of detail about the security you require. The access types allowed are:

readcontrols read access.
writecontrols write, delete and rename access.
allcontrols all access.

The pairs are processed in the order they appear, with later pairs modifying the effect of earlier pairs. This permits setting one type of access without explicitly setting all others. For example,

secure [
    net allow
    file [
        ask all
        allow read
    ]
]

sets the security level to ask for all operations except for reading which is to be allowed.

This technique can also be used for individual files and directories. For example:

secure [
    net allow
    file quit
    %source [ask read]
]

asks if an attempt is made to read the %source directory. Otherwise, it uses the default (quit).

There is a special case in which the secure function takes a single word argument that must be one of the security access levels. In that case, the security level for all network and file access is set to that level. This is very similar to the previous syntax except that there is no way to specify separate read and write access.

secure quit

The secure function also accepts none, allowing access with no restrictions (same as allow).

The default security level (which corresponds to the old read level) is now:

secure [
    net allow
    file [
        ask all
        allow read
    ]
]

If no security access level is specified for either network or file access, it defaults to ask. The current settings will /not/ be modified if an error occurs parsing the security block argument.

Prior Security Settings

The secure function now returns the prior security settings before the new settings were made. This is a block with the global network and file settings followed by file or directory settings. The query word can be used to obtain the settings without modifying them.

current-security: secure query

You can modify the current security level by querying the current settings, modifying them, then using the secure function to set the new values.

As in the past, lowering the security level produces a /change security settings/ request. The exception is when the REBOL session is running in /quiet/ mode which will, instead, terminate the REBOL session. No query is generated when security levels are raised. Note that the security request now includes an option to allow all access for the remainder of the scripts processing.

Note that the -s argument is equivalent to secure allow. The +s arguments is equivalent to secure quit. You can now follow the --secure argument with one of the security access levels for both network and file access:

rebol --secure throw

Protect

It is often convenient to protect words from being unintentionally redefined. The new protect and unprotect functions allow a word or a block of words to be protected and unprotected from redefinition. The protect function can be used to protect the words used for functions and system values to minimize accidental attempts to modify them in a script and produce an error. For example,

protect 'help

will protect the help word from being globally redefined. If your script attempts to redefine help, an error will occur:

>> help: now
** Script Error: Word help is protected, cannot modify.
** Where: help: now

Groups of words can also be protected by placing them in a block:

protect [help what probe]

The unprotect function works in a similar manner:

unprotect 'help

unprotect [help what probe]

If the word is used in a local context, then its definition will not be restricted by this protection.

test: func [/local help] [help: 10 print help]

No error occurs, because help is defined locally to the function.

Note that protect only protects words and not their values, such as the elements of a series or object.

The new protect-system function protects all globally-defined functions as well as the system object. An unprotect-system function is not in REBOL/Core, but can be implemented from the source of the protect-system function.

Note: The definition of protect prior to release 2.2 was used for setting the catch attribute of functions. This was a temporary, unsupported function and its result can now be accomplished with function attributes.

Function Attributes

A function's attributes provide control over special attributes of functions, such as the method a function uses to handle errors or exits. The attributes are an optional block of words that follow the optional function description and precede the function's arguments. There are currently two attributes: catch and throw.

Error messages typically are displayed as they occur within the function. The catch attribute, instead, redirects errors to where the function was called. This is useful for handling generic types of errors that may occur in system mezzanine functions. For example:

my-func: func [
    "test function" [catch] 
    arg [integer!]
    ][
    if arg <0 [
        [throw make error! "only positive integers"] 
        negate arg
    ]
]
my-func 2
-2

my-func -2
**User Error: only positive integers
**Where: my-func 2

Note: The catch attribute was previously set using a previous form of the protect native. This use of protect is no longer valid; any scripts that use protect in this way will generate an error.

The throw attribute forces a return or exit to the next higher function level, rather than just the function that is being evaluated.

New Functions and Refinements

The following new functions and refinements are incorporated in to REBOL/Core 2.2:

Build-Tag

build-tag composes an HTML or XML tag from a block of words and values. If build-tag encounters text surrounded by parentheses, then it will evaluate the expression and place the result within the tag. Example:

file: %index.html
build-tag [A HREF (join http://www.rebol.com/ file)]
<A HREF="http://www.rebol.com/index.html">

build-tag [font face "helvetica" color 
(either now/time > 10:00 ["red"]["blue"])]
<font face="helvetica" color="red">

Refer to documentation on the compose function for more information on how such expression blocks work.

Reverse

reverse accepts any series or tuple and reverses the order of its elements. If reverse is passed a series with the index past the head, the series is reversed from the index position onward. If the /part refinement is specified, only the specified number of elements will be reversed from the index forward. Specifying zero as the /part will produce no effect. reverse returns the series at the end of the affected region of the series. Example:

reverse 1.2.3.4
4.3.2.1

a: "LOBER"
reverse a
print a
"REBOL"

Forever

The forever function repeatedly evaluates a block until a break (or some other throw type function) occurs. Example:

forever [print "hello"]

Prints hello forever.

Difference

The difference function returns all elements within two series not existing in both. This function can be used for processing data sets along with the union and intersect functions. The function also accepts bitsets for its arguments.

difference [1 2 3 4] [1 2 3 5]
[4 5]

difference [Bill Bob Bart] [Bob Ted Fred]
[Bill Bart Ted Fred]

The /only refinement returns all elements within the first series not found in the second series.

difference/only [1 2 3 4] [1 2 3 5]
[4]

difference/only [Bill Bob Bart] [Bob Ted Fred]
[Bill Bart]

The /case refinement uses a case-sensitive comparison.

difference/case [Bill Bob Bart] [bill bob bart]
[Bill Bob Bart bill bob bart]

Replace

The replace function searches the target series for specified data and replaces it. It takes three arguments: a /target/ series, a /search /series, and a /replace/ series. The function will find the /search/ series in the /target/ series and replace it with the /replace/ series. The /all refinement will replace all occurrences of the /search/ string with the /replace/ string. The replace function returns the /target/ string at the original position. Example:

replace "string" "str" "th"
"thing"

replace ["this" "on" "here"] "on" "one"
["this" "one" "here"]

replace "abxyz" "xyz" "cde"
"abcde"

Literal Paths

The lit-path! function is a new literal path datatype that creates a path literal. When stored in a word, a path literal has the same behavior as a path created using make path!. Example:

test: 'now/time
now/time

test
0:55:42

type? first ['now/time]
lit-path!

Resend

The resend function resends an email message to the specified email without alteration, leaving the original "T" and "Fro" fields intact. The recipient and sender email addresses specified with resend are assigned to the fields "Delivered-T" and "Return-Pat" within the resent email. Messages resent must be passed to resend as a single string value containing the email. Example:

resend luke@rebol.com me@here.dom some-message

Resend is useful for relaying email without affecting the email content or its header. For example, use resend to forward your email to another computer without changing the header. It should only be used to resend valid email messages.

Email Paths

Path actions on an email datatype now include /user and /host. The /user refinement returns a copy of everything before the /at (@)/ symbol in the email. The /host refinement returns a copy of everything after the /at (@)/ symbol. Setting the /host or /user refinement to a string datatype will cause these portions of the email to be changed to that datatype. For instance,

email: fred@rock.dom
email/user: barney
print email
barney@rock.dom

The mechanism accepts all datatypes, forming those that are not string series datatypes.

Do/next

The do/next function/refinement will accept and evaluate the next item. The refinement accepts a string, file, or block. Strings and files are loaded into a block, then do/next returns a block containing two items. The first item is the result of the next doable REBOL item. The second item is the loaded block pointing just after the evaluated expression. Example:

mark: [1 + 1  4  reverse copy "hello"]
until [
    set [item mark] do/next mark
    print item
    tail? mark
]

2
4
olleh

Load/next

The load/next function/refinement loads the next item. It accepts a string or a file and returns a block containing two items. The first item is the next loadable REBOL datatype from the series. The second item is the series offset pointing into the original operand series just beyond the loaded data result string. Example:

mark: {join http://www.rebol.com/ %index.html}
until [
    set [item mark] load/next mark
    print type? item
    tail? mark
]

word!
url!
file!

Append/only

The append/only function/refinement appends a block as a single value. This is similar to insert/only. Example:

append [a b c] [1 2 3]
[a b c 1 2 3]

append/only [a b c] [1 2 3]
[a b c [1 2 3]]

Find/last and /reverse

The /last refinement causes find to search from the series tail to the current position.

blk: skip [a b c a b c a b c] 3
[a b c a b c]
find/last blk [a]
[a b c]

The /reverse refinement causes find to search from the current position in the series to the head. Example:

blk: skip [a b c a b c a b c] 3
[a b c a b c]
find/reverse blk [a]
[a b c a b c a b c]


Feedback

REBOL Technologies is very interested in the problems you may have found. To report a bug, use the feedback script included with this release. Start REBOL, then enter:

do %feedback.r

If your REBOL system is configured to send email, the script will prompt you for information, then email your information directly to our support department.

Alternately, send an email message (no HTML or enclosures). Please write a subject line that describes the problem. Write something like "making blocks does not work" rather than just "bug". Email:

feedback@REBOL.com <mailto:feedback@rebol.com>

We will send an automatic confirmation of each report. If you don't get the confirmation, then we may not have received your email or the return address is incorrect.

Be sure to give us a simple example of the problem within the bug report. If it occurs in a large script, edit it down to just the bug. Please don't send large files.

Also, be sure to include the version number as is printed in the title banner. It indicates not only the version and revision, but also the update number and the platform (OS). For example,

2.2.0.3.1

indicates that you are running Version 2.2.0 for the Windows 95/98/NT. Version numbers have the format:

version.revision.update.platform

From the REBOL language you can obtain the version number with:

print REBOL/version
About | Contact | Support | Privacy | LicenseREBOL Technologies 2016