REBOL/Core Changes
Versions 2.5.1 - 2.5.5 REBOL Technologies
Contents:
1. Core Version 2.5.5
1.1 Main Purpose
1.2 New Core License
1.3 Startup Files (user.r and rebol.r)
1.4 How Scripts are Started
1.5 Command Line Terminator (CR)
1.6 Changes to SECURE
1.7 MOLD/Flat Refinement
1.8 Truncation of Series Index (when Past Tail)
1.9 AT on PORTs
1.10 Added SIXTH Through TENTH Functions
1.11 Lines Longer Than 4 KB in Direct/Lines Mode
1.12 DECODE-CGI Handles Duplicate Names
1.13 ALTER Fixed
1.14 Network Errors in TRY (Net-Error Throw)
1.15 Extended FTP Directory Paths
1.16 STATS for SYSTEM/STATS
1.17 PURL Captured
2. Core Version 2.5.3
2.1 Credits
2.2 MAKE-DIR Rewritten
2.3 New Bitset Functions: CLEAR, LENGTH?, EMPTY?
2.4 Changes to SKIP Function
2.5 ARRAYs Initialized with Block Values
2.6 Added PARSE BREAK Word
2.7 Fix to OPEN on Network Ports
2.8 Fixed Crash on Modified Functions
2.9 CHANGE Accepts Any Type Value
2.10 Unset Object Variables (on Exit)
2.11 Added BUILD-MARKUP Function
2.12 Revised BUILD-TAG Function
2.13 Revised DECODE-CGI Function
2.14 UNPROTECT Fixed
2.15 ALTER added to Core
2.16 SYSTEM Word Protected
2.17 Error Message for Word Context
2.18 Fixed Crash on Future Dates
3. All Products - Core Version 2.5.2
3.1 CONSTRUCT Object Creator
3.2 LOAD Change (Important)
3.3 HELP Expanded
3.4 SUFFIX? Function Added
3.5 SIGN? Function Added
3.6 COMPONENT? Function Added
3.7 SEND Function Updated
3.8 Miscellaneous Fixes
3.8.1 TYPE? (As used in PARSE)
3.8.2 MOLD/ALL
3.8.3 FTP
4. All Products - Core Version 2.5.1
4.1 Source Code Form for Values of NONE, TRUE, etc.
4.2 Less Aggressive Evaluation (Important!)
4.3 COMPOSE/ONLY Inserts Blocks
4.4 REMOVE-EACH - Easy Series Element Removal
4.5 ATTEMPT for Error Handling
4.6 EXTRACT Function Updated
4.7 SAVE to Memory
4.8 SEND Refinements /Subject /Attach
4.9 Difference for Date/time
4.10 System Port Added
5. Interpreter Fixes
6. Networking Fixes
7. Other Function Fixes
1. Core Version 2.5.5
1.1 Main Purpose
The primary purpose of the Core 2.5.5 release is to bring
REBOL/Core into closer compatibility with the new Mac OS X and
REBOL/SDK kernels.
1.2 New Core License
REBOL/Core licensed has changed to allow personal, educational,
or commercial use of the CORE software free of charge.
Note that this license change only applies to REBOL/Core (and
will be added to the next release of REBOL/View), but it does
not apply to REBOL/SDK, /Command, /IOS or other REBOL commercial
products.
1.3 Startup Files (user.r and rebol.r)
Beta V2.5.4 did not evaluate the rebol.r and user.r files.
V2.5.5 evaluates them again, although using a slightly different
method. This should not affect your program. The order is still:
- Check the current directory first.
- Check the system/options/home directory second.
This allows you to have a single standard rebol.r file (and
optionally a user.r file) that is shared by all users on
multiuser systems.
1.4 How Scripts are Started
The method used to start initial scripts has been modified.
This change will have no affect on your programs, but it will
produce a better error message on script errors by eliminating
the error line that refers to the problem being "Near do-boot".
That line was confusing to new users, because do-boot was not
part of their script file.
1.5 Command Line Terminator (CR)
REBOL no longer shows Usage info if a CR char is passed from
a Unix shell on the shell command line.
Although REBOL scripts properly read and load with respect to
the CR (ASCII 13) character, some operating systems will pass
the CR as a command line argument, causing older versions of
REBOL to print its usage help information.
For example, you might see a problem with a CGI shell script
starting with:
#!/home/user/rebol -cs
REBOL [...]
|
that was written on a Windows system and transferred to Linux
without converting line terminators.
This case has been fixed.
1.6 Changes to SECURE
Beta V2.5.4 did not set SECURE prior to running scripts (in
other words, it functioned like REBOL/Base).
With V2.5.5 security is being set again, although with a slight
change: by default you can now write to a script's target
directory. For example, if you run:
REBOL /home/test/script.r
|
REBOL will startup with WRITE access to /home/test. All other
directories will be set to READ only (with WRITE ask).
This change makes it easier for users to write scripts that
write and update local data files without the need to provide a
-S command line option, but it still protects the rest of your
files.
Note that the +S command line option has also been changed.
Previously, +S meant SECURE QUIT, which was almost useless
because your REBOL would QUIT as soon as it tried to read its
rebol.r and user.r files. Now +S means SECURE ASK, so running
with:
Will prompt the user for all READ/WRITE operations for files and
networking. A safe mode of operation, but less strict than
before.
In addition, the --secure options should also work again now:
rebol --secure allow script.r
rebol --secure ask script.r
|
1.7 MOLD/Flat Refinement
The /flat refinement allows you to MOLD code and data without
line indentation, making the resulting string smaller (for sending
over a network, storing as compressed data, encapping, etc.).
For example:
blk: [
name [
first "Bob"
last "Smith"
]
options [
colors [
red
green
blue
]
]
]
>>print mold blk
[
name [
first "Bob"
last "Smith"
]
options [
colors [
red
green
blue
]
]
]
>> print mold/flat blk
[
name [
first "Bob"
last "Smith"
]
options [
colors [
red
green
blue
]
]
]
|
1.8 Truncation of Series Index (when Past Tail)
The handling of an "past the tail" series index has been changed.
In prior versions of REBOL, referring to a series past its tail
would cause an error:
>> a: "ABC"
== "ABC"
>> b: next a
== "BC"
>> clear a
== ""
>> insert b "X"
** Script Error: Out of range or past end
** Near: insert b "X"
|
In some situations, this problem could become difficult to detect,
because nearly any reference to B would cause the error.
>> tail? b
** Script Error: Out of range or past end
** Near: tail? b
|
As a result, the "past end" handling has been relaxed. For many
functions, the index will now truncate to the current tail of
the series:
>> a: "ABC"
== "ABC"
>> b: next a
== "BC"
>> clear a
== ""
>> tail? b
== true
|
1.9 AT on PORTs
The AT function (similar to the SKIP function) now works for the
Port datatype.
1.10 Added SIXTH Through TENTH Functions
Five new ordinal functions have been added:
sixth
seventh
eighth
ninth
tenth
|
The benefit of these function becomes more clear when you
consider using them to pick values from a series (instead of
using an object field).
name-of: :first
age-of: :second
date-of: :third
...
product-of: :ninth
...
if empty? product-of record [print "missing product"]
|
The line above is much more readable than:
if empty? ninth record [print "missing product"]
|
Here's a handy utility function for creating such named
accessors:
ordain: func [
"Defines ordinal accessors (synonyms)."
words [block!] /local ords
][
ords: [first second third fourth fifth
sixth seventh eighth ninth tenth]
foreach word words [
set word get first ords
ords: next ords
]
]
|
The above example would then be simplified to:
ordain [name-of age-of date-of ... product-of]
...
if empty? product-of record [print "missing product"]
|
Question: Would you like to see ordain become a regular
function in REBOL? Tell us via Feedback.
1.11 Lines Longer Than 4 KB in Direct/Lines Mode
Earlier versions of REBOL did not properly expand their internal
line buffers beyond 4 KB for files opened in direct/lines mode.
As a result, lines longer than 4 KB (no line terminators for
more than 4 KB) would not be read correctly and would cause an
end of file. This problem has been fixed in the current release.
1.12 DECODE-CGI Handles Duplicate Names
With increased use of REBOL for CGI scripts, we've expanded
the DECODE-CGI function to handle duplicate name fields.
For example, checklists used in web forms may return multiple
values for a single variable. DECODE-CGI will now make these
multivalued returns into blocks:
>> cgi-str: {name=bob&option=view&option=email&}
>> decode-cgi cgi-str
== [name: "bob" option: ["view" "email"]]
|
1.13 ALTER Fixed
A serious error in the ALTER function (a data set flagging
function, see updated docs in The REBOL
Dictionary) caused it to malfunction. This problem has been
fixed.
1.14 Network Errors in TRY (Net-Error Throw)
The NET-ERROR function used THROW for errors, rather than just
letting the error throw itself. This caused some types of
network errors to bypass a higher level catch when using TRY.
This meant that if you used a TRY around sections of your code,
certain network errors (such as an SMTP problem) may be thrown
past it, which would cause the error to be passed all the way
out to user at the console. This was a problem for SDK scripts,
and has been fixed.
1.15 Extended FTP Directory Paths
When using FTP URLs, there was no easy way to provide a full path
from the root directory.
For example, your logon directory may be:
but you want to refer to:
In the new release, you can use a double slash URL to provide
the absolute directory path:
read ftp://user:pass@host//var/log/messages
|
(Please tell us if you have any problems using this format.)
1.16 STATS for SYSTEM/STATS
The STATS function is now directly accessible. You no longer need
to use SYSTEM/STATS.
In addition, the STATS function now more accurately computes
memory usage.
1.17 PURL Captured
The variable PURL used in DECODE-URL is now a local variable
rather than a global.
2. Core Version 2.5.3
2.1 Credits
Thanks go to these contributors for their feedback, suggestions, or
solutions:
Andrew Martin
"Anton"
Cal Dixon
Carl Sassenrath
Ernie van der Meer
Gregg Irwin
Ladislav Mecir
Maarten Koopmans
"Mr. Martin Mr. Saint"
Reichart Von Wolfsheild
|
Did we miss your feedback or contribution to fixes or improvements?
If so, tell us at:
http://www.rebol.com/feedback.html.
It is not always possible to get every change into each new
release, but if you have found a bug that's causing you
problems, please let us know and we'll do our best to fix it.
Provide a very short, repeatable example of the problem, and if
you have a fix to the problem, send that along as well. (You'll
see the fix happen much faster that way.)
2.2 MAKE-DIR Rewritten
The MAKE-DIR function has been rewritten and now works
correctly. In addition, it has been relaxed to not cause an
error when the specified directory exists. Use the EXISTS?
function if you need to check that.
2.3 New Bitset Functions: CLEAR, LENGTH?, EMPTY?
Three new functions (actions) have been added to bitsets:
The CLEAR function quickly clears all bits to zero.
The LENGTH? function returns the number of bits in the bitset
(always multiple of 8).
The EMPTY? function returns TRUE if any bit is set, otherwise
it returns FALSE. (Note that EMPTY? is the same function as
TAIL?; therefore, TAIL? also returns the same results, but the
word has no meaning for bitsets.)
Bitsets are used as high performance logic arrays for character
sets and hashes.
Examples:
>> items: make bitset! 40
== make bitset! #{0000000000}
>> length? items
== 40
>> empty? items
== true
>> insert items 10
== make bitset! #{0004000000}
>> empty? items
== false
>> clear items
== make bitset! #{0000000000}
>> empty? items
== true
>> empty? negate items
== false
|
2.4 Changes to SKIP Function
There are three changes to SKIP that you should note:
1. SKIP now handles decimal offsets correctly. Values are
truncated down to lower integer value. (Note that decimal
offsets should be used with caution because 1.9999999 is not the
same as 2.0 when it comes to indexing.)
>> skip "abc" 1.9999999
== "bc"
>> skip "abc" 2.0
== "c"
|
2. SKIP can have a logic offset. It is made consistent with PICK
and AT when used with logic offsets.
>> pick [red green] true
== red
>> skip [red green] true
== [red green]
>> at [red green] true
== [red green]
>> pick [red green] false
== green
>> skip [red green] false
== [green]
>> at [red green] false
== [green]
|
For logic offsets, SKIP is identical to AT.
3. SKIP on images will offset pixels, not RGBA bytes. This is
consistent with AT, PICK, and POKE. If you are currently using
skip on images, this change will affect your code.
2.5 ARRAYs Initialized with Block Values
If a block value is provided as the initial element value in
the ARRAY function, each element should be the block, not the
contents of the block.
In addition, if the initial value is a SERIES of any type (e.g.
string, block, email, url) it will be deep copied into each
array element (that is, the value of each element will be unique,
not shared).
As an example:
>> a: array/initial [2 3] [1 2]
== [[[1 2] [1 2] [1 2]] [[1 2] [1 2] [1 2]]]
>> append a/1/2 3
== [1 2 3]
>> a
== [[[1 2] [1 2 3] [1 2]] [[1 2] [1 2] [1 2]]]
|
2.6 Added PARSE BREAK Word
Within some types of PARSE loops such as ANY and SOME, it can
sometimes be difficult to write rules that terminate the loop.
This happens primarily when using general rules that try to
capture "all other cases" within the loop. For example, code
such as:
parse item [
any [
"word" (print "got word")
| copy value [to "abc" | to end]
(print value)
]
]
|
will end up looping forever because the second rule within the
ANY will always succeed, and the ANY will never terminate.
To help solve this problem, the BREAK keyword was added to the
parse dialect. Its use is simple. When the BREAK word is
encountered within a rule block, the block is immediately
terminated regardless of the current input pointer. Expressions
that follow the BREAK within the same rule block will not be
evaluated.
The above example can now be written as:
parse item [
any [
"word" (print "got word")
| copy value [to "abc" | to end]
(print value) break
]
]
|
The ANY loop will be terminated after the second rule.
Generally, for ANY rule blocks that need to terminate at the end
of the input stream, you can add an END check followed by the
BREAK keyword, such as in this example:
parse item [
any [
end break
| "word" (print "got word")
| copy value [to "abc" | to end]
(print value)
]
]
|
2.7 Fix to OPEN on Network Ports
OPEN on network port under some versions of Windows32 would fail
due to an incorrect error code returned from WinSock library (as
documented by Microsoft). Fixed.
2.8 Fixed Crash on Modified Functions
Fixed the crash that happened when modifying a function's value
while evaluating its arguments. For example, the code below:
a: func [x] [print x]
b: func [] [a: 42]
a b
|
no longer causes a crash.
Note that modifying a function while it is evaluating may
produce odd results that may vary between implementation
versions and should generally be avoided.
2.9 CHANGE Accepts Any Type Value
To be consistent with INSERT, the CHANGE function allows
a new value to be any datatype (ANY-TYPE!).
Users should be aware that a missing value argument will
result in a CHANGE value of UNSET!, not an error.
For example:
>> a: [10]
== [10]
>> do [change a]
== []
>> probe a
[unset]
== [unset]
|
2.10 Unset Object Variables (on Exit)
If exit occurs during object evaluation, unassigned variables
not copied from parent object are unset. Fixes the "end" bug
where the first variable was set to the END! datatype.
>> probe make object! [exit a: b:]
== make object! [
a: unset
b: unset
]
|
2.11 Added BUILD-MARKUP Function
This function was inspired by the EREBOL concept of Maarten
Koopmans and Ernie van der Meer. Essentially, the idea is that
REBOL makes a powerful PHP style markup processor for generating
web pages and other markup text.
The BUILD-MARKUP function has been added to support this
operation, and will become a standard part of every REBOL
implementation.
The BUILD-MARKUP function takes markup text (e.g. HTML) that
contains tags that begin with "<%" and end with "%>". It
evaluates the REBOL code within each tag (as if it were a REBOL
block), and replaces the tag with the result. Any REBOL
expression can be placed within the tag. As PHP has shown, this
is a very useful technique.
For example:
== build-markup "<%1 + 2%>"
>> "3"
== build-markup "<B><%1 + 2%></B>"
>> "<B>3</B>"
== build-markup "<%now%>"
>> "2-Aug-2002/18:01:46-7:00"
== build-markup "<B><%now%></B>"
>> "<B>2-Aug-2002/18:01:46-7:00</B>"
|
Supplying a <%now%> tag to BUILD-MARKUP inserts
the current date/time in the output.
Here's a short example that generates a web page from a template
and a custom name and email address:
template: {<HTML>
<BODY>
Hi <%name%>, your email is <i><%email%></i>.<P>
</BODY>
</HTML>
}
name: "Bob"
email: bob@example.com
page: build-markup template
|
Don't forget the two % characters within the tag. It's a common
mistake.
The value that is returned from the tag code is normally
"joined" into the output. You can also use FORM or MOLD on the
result to get the type of output you require. The example below
loads a list of files from the current directory and displays
them three different ways:
Input: "<PRE><%load %.%></PRE>"
Result: {<PRE>build-markup.rchanges.txt</PRE>}
Input: "<PRE><%form load %.%></PRE>"
Result: {<PRE>build-markup.r changes.txt</PRE>}
Input: "<PRE><%mold load %.%></PRE>"
Result: {<PRE>[%build-markup.r %changes.txt]</PRE>}
|
If the evaluation of a tag does not return a result (for example
using code such as print "test"), then nothing is output. In
this case, the output of PRINT will be sent to the standard
output device.
Input: {<NO-TEXT><%print "test"%></NO-TEXT>}
test
Result: "<NO-TEXT></NO-TEXT>"
|
The BUILD-TAG function can be used within the tag for converting
REBOL values into markup output:
Input: {<%build-tag [font color "red"]%>}
Result: {<font color="red">}
|
Tags can set and use variables in the same way as any REBOL
script. For example, the code below loads a list of files from
the current directory, saves it in a variable, then prints two
file names:
Input: "<PRE><%first files: load %.%></PRE>"
Result: {<PRE>build-markup.r</PRE>}
Input: "<PRE><%second files%></PRE>"
Result: {<PRE>changes.txt</PRE>}
|
Note that variables used within tags are always global variables.
If an error occurs within a tag, an error message will appear
as the tag's result. This allows you to see web page errors
from any HTML browser.
Input: "<EXAMPLE><%cause error%></EXAMPLE>"
Result: {<EXAMPLE>***ERROR no-value in: cause error</EXAMPLE>}
|
If you do not want error messages to be output, use the /QUIET
refinement. The example above would result in:
Result: "<EXAMPLE></EXAMPLE>"
|
2.12 Revised BUILD-TAG Function
The previous version of BUILD-TAG generated poor results for
most input combinations. It has been replaced by a new function
that was contributed by Andrew Martin. This function produces
better results, but ones that are different from the previous
function. If you are currently using BUILD-TAG, you will need to
adjust your code.
In: [input "checked" type "radio" name "Favourite" value "cat"]
Old: {<input="checked" type="radio" name="Favourite" value="cat">}
New: {<input checked type="radio" name="Favourite" value="cat">}
In: [html xml:lang "en"]
Old: {<html="xml:lang"="en">}
New: {<html xml:lang="en">}
In: [body text #FF80CC]
Old: {<body text="FF80CC">}
New: {<body text="#FF80CC">}
In: [a href %Test%20File%20Space.txt]
Old: {<a href="Test File Space.txt">}
New: {<a href="Test%20File%20Space.txt">}
In: [/html gibber %Froth.txt]
Old: {</html gibber="Froth.txt">}
New: "</html>"
In: [?xml version "1.0" encoding "UTF-8"]
Old: {<?xml version="1.0" encoding="UTF-8">}
New: {<?xml version="1.0" encoding="UTF-8"?>}
In: [html xmlns http://w3.org/xhtml xml:lang "en" lang "en"]
Old: {<html xmlns="http://w3.org/xhtml"="xml:lang"="en" lang="en">}
New: {<html xmlns="http://w3.org/xhtml" xml:lang="en" lang="en">}
In: [html xmlns http://w3.org/xhtml/ xml:lang "en" lang "en"]
Old: {<html xmlns="http://w3.org/xhtml/"="xml:lang"="en" lang="en">}
New: {<html xmlns="http://w3.org/xhtml/" xml:lang="en" lang="en">}
|
2.13 Revised DECODE-CGI Function
Several bugs have been fixed in DECODE-CGI. More specifically,
the function handles empty attribute assignments. Here are some
examples:
Input: "name=val1&name=val2"
Decoded: [name: "val1" name: "val2"]
Input: "name1=val1&name2&name3=&name4=val3"
Decoded: [name1: "val1" name2: "" name3: "" name4: "val3"]
Input: "name1="
Decoded: [name1: ""]
Input: "name2&"
Decoded: [name2: ""]
Input: "name3=&"
Decoded: [name3: ""]
Input: "name4=val"
Decoded: [name4: "val"]
Input: "name5=val&"
Decoded: [name5: "val"]
|
The new function is based on Andrew Martin's contribution. Thanks!
2.14 UNPROTECT Fixed
Attempting to UNPROTECT a block containing any value other than
a word could cause a crash. Now non-word values are ignored.
2.15 ALTER added to Core
The ALTER function found only in View is general purpose and has
been made available in all version of REBOL.
2.16 SYSTEM Word Protected
To help prevent an accidental beginner mistake that is difficult
to debug, the SYSTEM and REBOL words are now protected. If you
need to change them, use UNPROTECT first.
2.17 Error Message for Word Context
The error message "word not defined in this context" has been
changed to "word has no context" to better indicate that the
word has never been defined (more precisely, never been bound)
in the context of an object, function, or global environment.
2.18 Fixed Crash on Future Dates
Prevents startup crash caused by error in Microsoft Windows time
functions when running with system date set to greater than 2036.
3. All Products - Core Version 2.5.2
3.1 CONSTRUCT Object Creator
We've added a "light-evaluation" object creator to provide a
higher level of security for imported data objects. The function
is called CONSTRUCT and it makes new objects, but without a
normal evaluation of the object's specification (as is done in
the MAKE and CONTEXT functions).
When you CONSTRUCT an object, only literal types are accepted.
Functional evaluation is not performed. This allows your code to
directly import objects (such as those sent from unsafe external
sources such as email, cgi, etc.) without concern that they may
include "hidden" side effects using executable code.
CONSTRUCT is used in the same way as the CONTEXT function:
obj: construct [
name: "Fred"
age: 27
city: "Ukiah"
]
|
but, no evaluation takes place. That means object
specifications like:
obj: construct [
name: uppercase "Fred"
age: 20 + 7
time: now
]
|
do not produce their evaluated results.
The CONSTRUCT function is useful for importing external
objects. For example, loading preference settings from
a file can done with:
prefs: construct load %prefs.r
|
Similarly, you can use CONSTRUCT to load a CGI or email
response.
To provide a template object that contains default variable
values (similar to MAKE), use the /AS refinement. The example
below would use an existing object called standard-prefs as the
template.
prefs: construct/as load %prefs.r standard-prefs
|
The CONSTRUCT function will perform evaluation on the words
TRUE, FALSE, NONE, ON, and OFF to produce their expected
values. Literal words and paths will also be evaluated
to produce their respective words and paths. For example:
obj: construct [
a: true
b: none
c: 'word
]
|
The obj/a value would be logical TRUE, obj/b would be NONE, and
obj/c would be WORD.
3.2 LOAD Change (Important)
Script header objects are now created by the CONSTRUCT function
and they are no longer evaluated.
This change provides a greater level of default security when
the LOAD function is used to load REBOL data. The change should
affect very few scripts (only those that depend on evaluated
header variables -- rare.)
The LOAD function can be used safely without the need to use
LOAD/ALL to inspect a script header prior to evaluation.
3.3 HELP Expanded
Help can now be used to explore the fields of an object in a
user-friendly format. For example, typing this line at the
prompt:
will produce this result:
SYSTEM is an object of value:
version tuple! 1.0.4.3.1
build date! 1-May-2002/13:31:11-7:00
product word! Link
components block! length: 45
words object! [unset! error! datatype! context! native
license string! {REBOL End User License Agreement IMPORT
options object! [home script path boot args do-arg link-
user object! [name email home words]
script object! [title header parent path args words]
console object! [history keys prompt result escape busy
ports object! [input output echo system serial wait-li
network object! [host host-address]
schemes object! [default Finger Whois Daytime SMTP POP I
error object! [throw note syntax script math access co
standard object! [script port port-flags email face sound
view object! [screen-face focal-face caret highlight-
stats native! System statistics. Default is to return
locale object! [months days]
user-license object! [name email id message]
|
This works for other types of objects as well as user-created
objects. The code below would display the contents of the
text-face object created by a View layout:
out: layout [text-face: text "test"]
help text-face
|
Sub-objects can also be viewed. They are specified as paths.
For example, to see the options object of the system object:
The result would look something like this:
SYSTEM/OPTIONS is an object of value:
home file! %/d/rebol/link/
script file! %/d/rebol/link/ranch/utilities/console.r
path file! %/d/rebol/link/ranch/
boot file! %/d/rebol/link/rebol-link.exe
args none! none
do-arg none! none
link-url string! "tcp://localhost:4028"
server none! none
quiet logic! true
trace logic! false
help logic! false
install logic! false
boot-flags integer! 2064
binary-base integer! 16
cgi object! [server-software server-name gateway-int
|
In addition, the search feature in help now provides more
information about matches that were made. If you type:
You will now see:
Found these words:
caret-to-offset native! Returns the offset position relative to
offset-to-caret native! Returns the offset in the face's text co
to-binary function! Converts to binary value.
to-bitset function! Converts to bitset value.
to-block function! Converts to block value.
to-char function! Converts to char value.
to-date function! Converts to date value.
to-decimal function! Converts to decimal value.
to-email function! Converts to email value.
to-event function! Converts to event value.
to-file function! Converts to file value.
to-get-word function! Converts to get-word value.
to-hash function! Converts to hash value.
to-hex native! Converts an integer to a hex issue!.
to-idate function! Returns a standard Internet date string.
to-image function! Converts to image value.
to-integer function! Converts to integer value.
to-issue function! Converts to issue value.
to-list function! Converts to list value.
to-lit-path function! Converts to lit-path value.
to-lit-word function! Converts to lit-word value.
to-local-file native! Converts a REBOL file path to the local
to-logic function! Converts to logic value.
to-money function! Converts to money value.
to-none function! Converts to none value.
to-pair function! Converts to pair value.
to-paren function! Converts to paren value.
to-path function! Converts to path value.
to-rebol-file native! Converts a local system file path to a R
to-refinement function! Converts to refinement value.
to-set-path function! Converts to set-path value.
to-set-word function! Converts to set-word value.
to-string function! Converts to string value.
to-tag function! Converts to tag value.
to-time function! Converts to time value.
to-tuple function! Converts to tuple value.
to-url function! Converts to url value.
to-word function! Converts to word value.
|
3.4 SUFFIX? Function Added
The SUFFIX? function is a helper function that returns the
file "extension" portion of a filename or URL. For example:
>> suffix? %into.txt
== %.txt
>> suffix? http://www.rebol.com/docs.html
== %.html
>> suffix? %test
== none
>> suffix? %test.it/file
== none
|
SUFFIX? can be useful when selecting files from a directory.
The example below will only select html and htm files:
foreach file load %. [
if find [%.html %.htm] suffix? file [
browse file
]
]
|
3.5 SIGN? Function Added
The SIGN? function returns a positive, zero, or negative integer
based on the sign of its argument.
print sign? 1000
print sign? 0
print sign? -1000
|
The sign is returned as an integer to allow it to be used
as a multiplication term within an expression:
new: 2000 * sign val
if size > 10 [xy: 10x20 * sign num]
|
3.6 COMPONENT? Function Added
COMPONENT? is a helper function that checks for the existence of
a named REBOL component.
if component? 'crypt [print "Encryption available."]
if not component? 'sound [print "No sound."]
|
3.7 SEND Function Updated
The SEND function now includes a /SHOW refinement that will show
all TO recipients in the header. By default, recipients are not
normally shown.
send/show [bob@example.com fred@example.com] message
|
In addition the FROM field will include the sender's name as well
as an email address. The string in system/user/name is used as the
from address. For example, if:
system/user/name: "Fred Reboller"
|
Then when the email is sent, the from field will now appear as:
From: Fred Reboller <fred@example.com>
|
If system/user/name is NONE or empty, it will not be used.
Finally, some problems in the /ATTACH refinement have been
fixed. Attachments of the form:
send/attach user content [[%file.txt "text message"]]
|
should work properly now. See 2.5.1 notes on SEND for more
information about /ATTACH.
3.8 Miscellaneous Fixes
3.8.1 TYPE? (As used in PARSE)
Fixed the problem reported in the TYPE? function that caused the
datatype error in PARSE. Code of the form below will work
properly now:
parse [34] reduce [type? 34]
parse [34.5] reduce [type? 34.5]
|
3.8.2 MOLD/ALL
Fixed the problem with function molding when /ALL refinement is
provided.
load mold/all context [test: func [arg] [print arg]]
|
3.8.3 FTP
Two fixes:
When connecting to a Microsoft IIS based FTP server Rebol did
not recognize folders correctly. They were marked as type
'directory but no slash was appended to the file name as done
with other types of FTP servers.
In FTP soft-links can now be identified. They can now return an
file type of 'LINK.
Thanks: Cal and Reichart at Prolific.com for submitting the
above FTP fixes.
4. All Products - Core Version 2.5.1
4.1 Source Code Form for Values of NONE, TRUE, etc.
To better support persistent values between SAVE, MOLD, and
LOAD, a new syntactic element has been added to REBOL.
In the past, the source code representation of values like NONE
and TRUE required evaluation in order to convert those words
into their actual values. For example:
would return the word NONE, not the value none. This required
that your code either evaluate the result (with DO, REDUCE, or
TRY) or manually convert the NONE word with code such as:
if value = 'none [value: none]
|
Thus, if you were storing REBOL data using MOLD or SAVE
functions, when you read the data back in, you would need to
either evaluate it (e.g. with REDUCE) or add checks for a few
specific types of words (as shown above).
To better handle this situation with the literal expression of
NONE, TRUE, FALSE, and other values that require evaluation, a
new syntactic form has been added to the language:
Where datatype indicates the datatype and value provides its
value. For simple datatypes such as NONE, TRUE, and FALSE the
shorthand form:
is also allowed. For example:
expresses the value NONE, not the word NONE, even with unevaluated
code or data. Similarly,
express the values of TRUE and FALSE within non-evaluated code.
The LOAD, DO, and other source translating functions have been
expanded to accept this new syntax. The example below helps show
the change:
block: load " none #[none] true #[true] "
foreach value block [print type? value]
word
none
word
logic
|
The literal expression of REBOL objects is also allowed by this
new format. For example the non-evaluated expression:
#[object! [name: "Fred" skill: #[true]]]
|
is equivalent evaluating:
make object! [
name: "Fred"
skill: true
]
|
Thus, a persistent (mold/load symmetric) form of objects now
becomes available to programmers.
To create or save source code or data using these new datatype
expressions, the MOLD and SAVE functions have been given a
new refinement called /ALL. This refinement will output the
new #[] format for necessary values. For example:
mold/all reduce ["Example" true none time]
|
word return the string:
["Example" #[true] #[none] 5-May-2002/9:08:04-7:00]
|
Similarly, using SAVE/ALL would store the above expression
to a file.
4.2 Less Aggressive Evaluation (Important!)
Variables are no longer aggressively evaluated.
In pervious versions of REBOL, variables that held set-words,
parens, paths, and other types of evaluative datatypes would be
evaluated on reference. That is no longer the case.
For example, in earlier versions, if you wrote:
the result would be an evaluation of b/c/d. This evaluation
caused problems because it is more common to reference such
data, not evaluate it. For instance, you want to be able
to write:
data: ["test" A: mold/only (10 + 2.5)]
foreach value data [print value]
|
and smoothly traverse the elements of the data block as simple
values. You would not want those values to self evaluate.
This change to evaluation has some deeper implications. For
example, it affects any function that specifies literal values
within arguments. For example, code such as:
f: func ['word] [print word]
|
The REBOL design definition of a literal function argument is to
accept the argument always as a literal value and NOT evaluate
it. However, in the actual implementation it turned out that an
evaluation would normally occur when the variable was referenced.
(As part of the PRINT in this case.)
For instance, if you passed:
within the function, the reference to the word would cause the
path to be evaluated at that point. Hence, if you referred to
the word argument three times, each time it would be evaluated.
This implicit and "aggressive" evaluation, while interesting, was
not intuitive and created to hard to find errors with difficult
to interpret error messages.
Consider the case where the set-word datatype might be passed
as the argument:
The set word is then evaluated where WORD appeared (in the PRINT
line), and it would require an argument. The code would produce
an error message that would tell you that the set required an
argument. Yet, you would see no set within your code. It would
look like an interpreter flaw, when in fact it was doing
precisely what you asked.
Since the vast majority of REBOL programs do not rely on this
type of evaluation, we've taken it out. This cleans up the
semantics of literal arguments, but it also means that where
programs depend on passing non-literals and assume that
evaluation occurs, they do not. That will break some code, but
it is rare. (For example, in the entire source code base of
REBOL Technologies, there was only one such case.)
4.3 COMPOSE/ONLY Inserts Blocks
The COMPOSE function now has an /ONLY refinement similar to the
INSERT/ONLY refinement. When /ONLY is specified, blocks that
are inserted are inserted only as blocks, not as the elements of
the block (the default). A REDUCE on the block is not required.
For example:
>> block: [1 2 3]
>> compose [example (block)]
== [example 1 2 3]
>> compose [example (reduce [block])]
== [example [1 2 3]]
>> compose/only [example (block)]
== [example [1 2 3]]
|
4.4 REMOVE-EACH - Easy Series Element Removal
The new function REMOVE-EACH works in a similar fashion to
FOREACH and makes removing values from strings, blocks, and
other series much easier.
Also, in most cases REMOVE-EACH is many times faster than using
a WHILE loop and the REMOVE function.
The format of REMOVE-EACH is identical to FOREACH except that
it uses the result of the block expression to determine removal.
REMOVE-EACH iterates over one or more elements of a series and
evaluates a block for each. If the block returns FALSE or NONE,
nothing is removed, but if the block returns any other value,
the items or items are removed.
remove-each value series [expression]
|
Similar to FOREACH, REMOVE-EACH can operate on multiple elements
from the series (and uses the appropriate skip to get to the next
set of elements):
remove-each [val1 val2 val3] series [expression]
|
Note that in addition to modifying the series, REMOVE-EACH also
returns the series as its result.
Here are a number of examples.
To remove the odd numbers from block:
>> blk: [1 22 333 43 58]
>> remove-each item blk [odd? item]
== [22 58]
>> probe blk
== [22 58]
|
To remove all numbers greater than 10 from block:
>> blk: [3 4.5 20 34.5 6 50]
>> remove-each item blk [item > 10]
== [3 4.5 6]
>> probe blk
== [3 4.5 6]
|
To remove all directories from a directory listing:
>> dir: load %.
>> remove-each file dir [#"/" = last file]
== [%calculator.r %clock.r %console.r %find-file.r...]
|
To keep only the directories in the listing:
remove-each file load %. [#"/" <> last file]
|
To remove keep only the .doc files from the listing:
remove-each file load %. [not suffix? ".doc"]
|
Here is an example of a block that uses multiple values:
blk: [
1 "use it"
2 "rebol"
3 "great fun"
4 "the amazing bol"
]
remove-each [num str] blk [odd? num]
remove-each [num str] blk [not find str "bol]
|
REMOVE-EACH also removes characters from a string:
>> str: "rebol is fun to use"
>> remove-each chr str [chr = #"e"]
== "rbol is fun to us"
>> remove-each chr str [find "uno " chr]
== "rblisfts"
|
4.5 ATTEMPT for Error Handling
The ATTEMPT function is a shortcut for the common REBOL idiom:
The format for ATTEMPT is:
ATTEMPT is useful in the cases where you either do not care
about the error result or you want to make simple types of
decisions based on the error.
ATTEMPT returns the result of the block if an error did not
occur. If an error did occur, a NONE is returned.
In the line:
value: attempt [load %data]
|
the value may be set to NONE if the %data file cannot be loaded
(e.g. it's missing or contains an error). This allows you to
write conditional code such as:
if not value: attempt [load %data] [alert "Problem"]
|
Or, even simpler:
value: any [attempt [load %data] 1234]
|
In this line, if the file cannot be loaded, then the value is
set to 1234.
4.6 EXTRACT Function Updated
The EXTRACT function now includes an /INDEX refinement to allow
you to specify what "column" you want to extract. For example:
data: [
10 "fred" 1.2
20 "bob" 2.3
30 "ed" 4.5
]
>> probe extract/index data 3 2
== ["fred" "bob" "ed"]
|
If index is not supplied, then the first column is extracted.
In addition, the extract function has been fixed to properly
extract blocks from a block series.
4.7 SAVE to Memory
The SAVE function can now write its results into memory. This is
useful because the SAVE function contains formatting refinements
that are found no where else.
To use SAVE to write to memory, specify a binary value rather
than a file name. For example:
bin: make binary! 20000 ; (auto expands if necessary)
image: load %fred.gif
save/png bin image
|
Now the BIN binary holds the PNG formatted image. It was not
necessary to write it to a file and read it back in.
4.8 SEND Refinements /Subject /Attach
The SEND function used for sending email has been extended to
easily allow a subject line to be specified with a /SUBJECT
refinement. This is a handy shortcut. For example:
letter: read %letter.txt
send/subject luke@rebol.com letter "Here it is!"
|
The above example will send the text of the letter with a
subject line as specified. If the /SUBJECT refinement is
not given, then the first line of the letter would be used
as the subject.
In addition, the SEND function can now include attachment files
by providing an /ATTACH refinement. A single file or multiple
files can be attached. The specified files can be read from disk
or can be provide as a filename and data. The formats are:
send/attach user letter file
send/attach user letter [file1 file2 ...]
send/attach user letter [[%filename data] ...]
|
You can also combine the last two above formats.
Example attachments are:
user: luke@rebol.com
letter: read %letter.txt
send/attach user letter %example.r
send/attach user letter [%file1.txt %file2.jpg]
send/attach user letter compose/deep [
[%options.txt (mold system/options)]
]
|
4.9 Difference for Date/time
The DIFFERENCE function will now provide the time difference
(hours, minutes, seconds) between two date/time values.
>> difference now 1-jan-2000
== 20561:20:26
|
Normally, when you subtract date/time the result is the number
of days, not time:
>> now - 1-jan-2000
== 856
|
4.10 System Port Added
The system port component was added. This component allows
direct access to various OS-specific features. For example, the
system port can catch Unix and Linux termination signals and
perform a controlled shutdown. Under Win32, this port can be
used to access win-messages.
More information about the System Port component will be
provided as a separate document.
5. Interpreter Fixes
The following internal interpreter problems have been fixed.
- Series Expansion: Significant performance and memory problem
has been fixed resulting in many times greater speed in some
types of uses. This change speeds up MOLD and SAVE by many
times.
- Lit-path! comparison works properly
- Time zone bug in date comparison fixed
- Handling of "--" in command line arguments
- Tab expansion of words in console
- Component version numbers added to the boot message
- Increased the global word limit to 8000
- Potential crash during expansion and recycling of hash! values
- Potential crash when recycling open, unreferenced ports
- Port cleanup to close ports in the correct order
6. Networking Fixes
The following fixes were made to networking:
- DNS - Unix only: fixed lockup when DNS helper process dies
unexpectedly.
- DNS - Unix only: DNS helper process no longer remains a
"zombie" if the main process is killed.
- FTP - conflicts with generic proxy setups fixed
- FTP - allow more response codes from CWD command in FTP
- HTTP - proxy authentication added
- HTTP - POST linefeed conversion problem fixed
- HTTP - forwarding fixed where host name in header was not updated
- POP - will try APOP if port/algorithm is set to 'apop (workaround for bug in some POP servers).
- TCP - On Windows only: TCP listen sockets no longer allow multiple
listeners on the same port. Workaround for bug in Windows TCP/IP
stack regarding SO_REUSEADDR.
7. Other Function Fixes
Fixes to natives and functions include:
- COMPRESS/DECOMPRESS - series offsets are now allowed
- DEBASE - potential crash fixed
- DEBASE - series offsets are now allowed
- FIND - when using bitset with chars greater than 127
- FIND/MATCH/CASE - fixed
- LOAD/MARKUP - potential crash fixed
- MAKE - potential crash with make object! object! fixed
- MAKE-DIR/DEEP - fixed bug
- SET-MODES - fixed file date setting when no time value is provided
- SORT - handles hashed blocks now, and potential crashes fixed
- UNION, INTERSECT, etc. - series offsets are now allowed on the second argument
| REBOL/MakeDoc 2.0 | 7-Mar-2003 |
Copyright 2003 REBOL Technologies REBOL is a registered trademark of REBOL Technologies
|