Miscellaneous
- What do the REBOL version numbers mean?
- How do I refer to a global word if it has been redefined locally?
- How is context different from scope?
- How does BIND work?
- Can I use REBOL with XML?
- How does REBOL evaluation work?
- How do I DO another script and pass it arguments?
- Why isn't REBOL open source?
- I'm getting way too much mail to read right now. How do I unsubscribe from the REBOL users
mailing list?
I/O
Q. How do I get REBOL
to not ask me for permission to write files each time I start it?
A. REBOL -s turns off the security from the command line. Type USAGE at the
prompt to see the rest of REBOL's command line switches.
Q. How do I write filenames
in REBOL?
A. Here are some examples of the format:
%/Volume/Directory/File - subdirectory
%/path - root of current volume
%//path - root of system
%path - relative file (based on the current directory)
%../path - up one level from the current directory
%. - current directory
If the file path starts with a slash, it is the root directory. If it doesn't, it is a subdirectory of the current
path.
Q. What high level directory
operations are available?
A. The directory functions are WHAT-DIR, CHANGE-DIR, LIST-DIR, and MAKE-DIR.
Lower level functions that operate on directories are READ, DELETE, QUERY, INFO?, RENAME, and MODIFIED?.
The current directory is seen by entering: WHAT-DIR
The directory REBOL is currently using can be changed using: CHANGE-DIR
To see all the files in the current directory use: LIST-DIR %path/
It is important to end directories with a slash.
Q. When I read a graphic
or compressed file from a web page, it is not the right size. Why?
A. Be sure to use the /BINARY refinements on READ and WRITE when dealing with
binary data:
write/binary %mypic.jpg read/binary http://web.page.org/pic.jpg
Q. How do I SEEK on a
file so I don't have to read the entire file?
A. You can't right now, but we are adding this ability. For now, you can OPEN
the file with the /LINES refinement and read it a line at a time:
open/lines %file
You can also open up a file with the /DIRECT refinement and read through until you arrive at the desired offset
within the file.
Q. There is no /BINARY
refinement available for PRINT. How do I output a binary value to stdout?
A. The REBOL console is a port, so it is actually very simple to output a binary
file:
data: read/binary %imagefile
write-io system/ports/output data length? data
CGI
Q. What do I have to do
to get REBOL scripts to run directly as CGI's?
A. Most of the time, all you have to do is add this line to the top of your
script:
#!/path/to/REBOL -c
Be sure to print out the content type headers at the beginning of your script so you can see any errors that
might occur, ie:
#!/path/to/REBOL -c
REBOL [
Title: "CGI Basics"
]
print ["Content-type: text/html" newline]
...
For more information see the cgi How To.
Q. How do I change a url-encoded
string back to its normal human-readable characters?
A. If what you have is a url datatype with url encoded characters you can just
use TO-STRING (which is short for make string!). If it is a string that has url encoded characters you can use
some of the code that is posted on the REBOL web site to decode it.
Q. When REBOL is started
with --cgi, should system/ports/output be opened with CR-LF as the default line ending?
A. At present it uses the local operating system default.
Ports/Networking
Q. Why don't some series
functions work on ports?
A. A port is an abstraction of a streaming data source. The abstraction allows
it to be treated as a series, however, some series operations do not always make sense with a stream data source.
That said, we are adding greater support for series operations on ports where they make sense.
Q. How do I set up my
proxy settings?
A. To specify a Proxy Server:
If you use a firewall with a proxy server, you can specify its settings:
set-net [
user@domain.dom
mail.server.dom
pop.server.dom
proxy.server.dom
1080
socks-type
]
where socks type is one of the following:
socks -- most recent version of SOCKS supported (currently SOCKS5)
socks4 -- SOCKS4 compatibility
socks5 -- SOCKS5 compatibility
generic -- generic proxy support (i.e. Squid)
A common way to determine the proxy type is to check your web browser settings. SOCKS has its own field while
generic proxies have settings specifically for HTTP, FTP, etc. in the browser preferences box.
Q. Is it possible to
get the last-modified date of a web page via REBOL?
A. Yes, use the MODIFIED? function, e.g.:
modified? http://www.REBOL.com
connecting to: www.REBOL.com
== 25-Jun-1999/22:20:16
The problem is that often web servers won't tell you the modification date and many web pages are dynamically
generated. MODIFIED? will return NONE in those cases. Your mileage may vary.
Q. Does REBOL FTP support
APPEND or RESTART commands?
A. REBOL's FTP implementation supports the APPEND command but not RESTART. To
use APPEND, try:
write/append ftp://some.site data
Q. Sometimes REBOL has
a network timeout error. How can I increase the network timeout value?
A. Setting:
system/schemes/default/timeout: 0:10
will give you a ten minute timeout.
Q. How can I get started
writing a protocol in REBOL?
A. Have a look at the port code within REBOL. The following will print all of
the protocols out:
foreach scheme next first system/schemes [
print mold get in system/schemes scheme
]
Also have a look at: SOURCE SEND and SOURCE NET-UTILS
Q. What is the SUB-PORT
in the port object hierarchy?
A. The sub-port is where the actual TCP port for the protocol is stored. TCP
ports, because they are lower level, don't have any default values. Instead, the values must be explicitly set
from the protocol.
Q. Inside the port code,
I see some functions, such as OPEN and INSERT written with fully qualified paths to SYSTEM/WORDS. Is this a context
thing?
A. The way a port-handler written in REBOL works is to contain functions that
map onto the native actions applied to the port. Thus, one function in the port is the OPEN function. Now, since
the OPEN function needs to open a TCP port, it must use system/words/open to avoid recursively calling itself.
Q. How can I pick several
characters at once from a port without using OPEN/LINES?
A. You can use copy/part to pick several characters at once.
Built-in Documentation
Q. How do I find out what
words are defined in the system?
A. Use the function: WHAT
Q. I notice when I try
to assign the return value of WHAT or HELP I get an error message instead. Why?
A. WHAT and HELP do not return a value to REBOL. To capture these, you could
do the following:
echo %what.txt what echo none
The function ECHO writes to a file everything that is printed to the console until it is turned off with ECHO
NONE.
Q. What if I want to write
a function that does the same thing as WHAT but returns a value?
A. REBOL allows the user to see the source code of all non-native functions.
Use the function SOURCE to see the code for WHAT and modify it as needed: SOURCE WHAT
System
Q. What is in the system
object?
A. The guts of REBOL.
The system object really is REBOL/core's object. It serves as a reference point for the language. We make it
visible, but we could also make it inaccessible. Play with it at your own risk.
version -- the version number of the REBOL build you're running
product -- the product name, ie REBOL/core, REBOL/author, REBOL/media
words -- the names of all the words defined in REBOL, including
words that you add
options -- various options and information about scripts
the cgi content-length and query-strings are both
under options/cgi
user -- settings for user email address and real name
script -- settings related to the script that was run
console -- settings for the console
ports -- storage for the raw console ports
network -- host and hostname
schemes -- the various network ports of REBOL are stored here along
with network port default values such as timeout
error -- error catalog
standard -- standard root objects used stored for later derivation
Q. I find that when I
type SOURCE SYSTEM, SOURCE REBOL, or PRINT SYSTEM, the computer will lock up. Why?
A. Viewing the system object should only be done with care. Future revisions
of the system object are going to change, therefore, use the mezzanine level functions to access system object
information when possible.
With that said, here is an example of viewing the system object:
>> print mold first system
[self version product words options user script console ports network
schemes error standard]
>> print system/product
Core
WARNING: DO NOT enter 'print mold second system' or 'print mold system' since this will cause the interpreter
to hang.
Q. REBOL won't find my %user.r
file. Why?
A. REBOL will by default look for the %user.r file in the directory where it
was started. However, setting the environment variable REBOL_HOME allows you to specify a directory for REBOL to
look for your user.r file.
Q. Why does REBOL take
so long to start on some of my older computers?
A. REBOL starts slow on some systems because much of the core is decompressed
upon startup. This is not very noticeable on newer systems because of the CPU MIPS ratings. However, the main loop
of the decompression code may be rewritten in assembly for some of the slower processors some time in the future.
Parse
Q. What are the basics
of PARSE?
A. Here are a few helpful notes on PARSE... however, this is somewhat terse
(we'll write a tutorial later)...
1. PARSE uses it's own dialect, which in REBOL lingo means that it can have its own grammar and vocabulary.
So, don't make any assumptions about any words that you see in a PARSE block, because they live in a separate context
and work differently. The great power and leverage of PARSE comes from this very fact, and that's why dialects
are the future...
2. Basic elements are:
[block] - a sub-rule to PARSE
"string" - attempt to match the string to the input
#"c" - attempt to match a single character to the input
- match tag to the input
(paren) - evaluate a REBOL expression
12 - repeat the pattern 12 times
1 12 - repeat pattern at least 1 but no more than 12.
word - look-up word in REBOL, it can be a number,
string, block, and PARSE will recognize it.
HOWEVER, PARSE also has keywords that are special.
word: - mark the current input series position in word
:word - set the current input series position from word
'word - (reserved for dialecting support :)
bitset - match any specified char in the set (more later)
3. The vocabulary (words) of PARSE is:
| - specify alternate rule (recovering input stream)
none - make previous rule optional
skip - skip any character (or chars if repeat given)
to - advance input to the given string (or char)
thru - advance input thru the given string (or char)
some - one or more of something
end - match against the end or to end
copy - copy the next match sequence to a word
Here is an example of PARSE in action:
digit: charset "0123456789"
expr: [term ["+" | "-"] expr | term]
term: [factor ["*" | "/"] term | factor]
factor: [primary "**" factor | primary]
primary: [value | "(" expr ")"]
value: [digit value | digit]
parse "1 + 2 ** 9" expr
== true
parse "math expression?" expr
== false
The above PARSE code determines if a given string contains a valid mathematical expression.
Datatypes
Q. What formats of binary
numbers are supported?
A. REBOL actually supports binary STRINGS. Of them, Base-2 (binary), base-16
(hexadecimal) and base-64 strings are possible.
You can convert these strings to integers, for instance:
10 = to-integer 64#{AAAK} = to-integer 16#{0A} = to-integer 2#{0000 1010}
You can turn an integer into a hexadecimal string with the TO-HEX function.
Integer (base-10) to binary is currently supported up to 32-bit signed numbers. The range is from -2147483647
to +2147483647.
Hex binaries must have an even number of digits, base-64 must have a multiple of 4 digits and base-2 must have
a multiple of 8 digits.
The binary datatype was included to assist in working with compressed data, image data (such as JPEGs), executables,
etc.
Q. What IS a series?
A. A series is a collection of one or more elements that can be ordered so that
you can get the FIRST element, the SECOND element, PICK the forty-second element, get the LAST element, etc...
The essential characteristics of a series are that it contains a set of values that are organized in a particular
order.
Q. How do I make an array?
A. Use the ARRAY function.
This creates an array foo which is 10 x 10. All the initial values will be set to none:
foo: array [10 10]
Use the /INITIAL refinement to specify an initial value:
foo: array/initial [10 10 10] 42
Elements of the array can be accessed by paths. The following would return the element in the fifth column and
fifth row, at a depth of five:
foo/5/5/5
This would set that same element to 13.
foo/5/5/5: 13
Q. How do I save a file
with spaces in it?
A. Use quote marks around the file name like this:
save %"a file with spaces" data
or
save to-file "a file with spaces" data
While most modern operating systems can store filenames with spaces, not all of them can handle much punctuation,
so go easy on the punctuation in filenames or you may make your script less portable.
Q. Are there any advantages
to using lists verses blocks?
A. The advantages occur with large lists when doing inserts or removes. On a
large block, all the data gets shuffled doing an insert at the head, while on a list, existing data is never moved.
This means that lists take more space than blocks since there is a linked list associated with the data. However,
the speed advantages are significant. Here's an example:
>> blk: make block! 20000
== []
>> t: now/time loop 20000 [ insert head blk 1 ] now/time - t
== 0:00:35
>> lst: make list! 20000
== make list! []
>> t: now/time loop 20000 [ insert head lst 1 ] now/time - t
== 0:00
Note, that the time for blk is not linear with the number of iterations since the amount of data that must be
moved with each insert becomes larger and larger.
Q. What do I use a HASH!
for?
A. Data that you are going to perform many searches on. Hashes are one of the
fastest data structures for search and retrieval. REBOL hashes can also be sorted using the SORT function.
Functions
Q. I noticed REBOL has
built-in compression. How do I use it?
A. Use the functions COMPRESS and DECOMPRESS. COMPRESS converts a string into
a compressed binary, and DECOMPRESS takes a compressed binary and returns the original string. The COMPRESS function
is comparable to ZIP or LHA in shrinkage.
DECOMPRESS COMPRESS "A string"
== "A string"
Q. Why doesn't REBOL have
an ELSE statement?
A. EITHER is used in place of IF/ELSE.
ELSE complicated the language because it had to be searched for each time an IF was encountered.
The syntax for EITHER is: either condition [true-block][false-block]
EITHER returns the value of the block it evaluates.
Q. Why doesn't my block
get reset each time? f: func [][ x: [] append x "a" ]
A. X points to that literal block. To get a new block each time you have to
say:
x: copy []
This is true for other literal series as well.
Q. What does the /LOCAL
refinement in the function argument list do?
A. Everything that follows the /LOCAL refinement is a local variable. Because
these variables are defined as arguments to the function their definition is quicker than if defined within a USE
block.
Q. How do I find out about
a particular function of the system?
A. Use the HELP function and the SOURCE function.
Q. How does the /COMPARE
refinement work with the SORT function?
A. Use the /COMPARE refinement to provide a function that performs the comparison
between two different elements:
sort/compare ["a" "B" "c"] func [a b][b < a]
would perform the reverse sort than the default.
Enhancements
Q. Can REBOL launch other
programs?
A. No. Launching other programs breaks the language portability. Some disagree
with this, but that's the way we see it. To get around this, crafty individuals have used files or sockets as a
method of communication to other processes which launch external applications.
The REBOL/Command version will have the ability to launch other programs built-in, however.
Q. Any plans to support
IMAP? LDAP?
A. Yes.
Q. How about ODBC?
A. Yes, in the Command version.
Miscellaneous
Q. What do the REBOL version
numbers mean?
A. Version, revision, release, system, variation. See www.REBOL.com/releases.html
for a complete list.
The OS numbers can be used by scripts to determine what kind of machine they are running on.
Q. How do I refer to a
global word if it has been redefined locally?
A. Use a fully qualified path to the word in system/words:
a-print: func [print [string!]][
system/words/print print
]
The word print is used as an argument which makes it local to the function. To get the original print function
you must specify a path to its global definition in the system object.
Q. How is context different
from scope?
A. Context is a larger concept than scope. Context includes things like the
different environments of distributed code running from one computer to another computer.
Much of the time, however, you can think of context and scope as the same thing.
Q. How does BIND work?
A. BIND takes a block of words and BINDs them into the current context. It takes
a word from the context you want to BIND to as its second argument. Try playing with this example:
REBOL [Title: "BIND Demo"]
global: on
x: 1 y: 2 z: 3
local-context: func [/local context][
use [x y z ] [set [x y z] [a b c] print bind [x y z] 'context]
]
global-context: func [][
use [x y z] [set [x y z] [a b c] print bind [x y z] 'global]
]
local-context global-context halt
LOCAL-CONTEXT prints a b c GLOBAL-CONTEXT prints 1 2 3
LOCAL-CONTEXT'S BIND is actually redundant. GLOBAL-CONTEXT's BIND uses the word 'global to cause the values
of X Y and Z be set to their values where the word 'global is defined, which happens to be out in the global context.
You may also BIND to other contexts besides the global context.
Q. Can I use REBOL with
XML?
A. There is some XML code on the web site in the scripts library. A built-in
XML parser is planned for REBOL/core 2.1.
Q. How does REBOL evaluation
work?
A. Evaluation is left to right, though application is right to left.
If you have:
word1 word2 word3
Word1 is evaluated, then word2, then word3.
However, if word1 is a function with one argument then word2 is evaluated before it is passed to word1. Similarly
with word2 to word3. If word1 is a function that takes two arguments then word2 and word3 must both be sequentially
evaluated, but in this case from right to left before being passed into word1. Thus application is right to left.
If instead you have:
do word1 word2 word3
and word1 creates and returns a function that takes two arguments, word2 and word3 will be evaluated before
being passed into the anonymous function that is returned from word1.
This causes an error:
if length? "zappo" < 22 [do something]
Parens are necessary around LENGTH? and "zappo" because the evaluation simply moves along from left
to right. IF is evaluated. It requires a condition arg and a block to DO if condition is true, so it sees LENGTH?
and LENGTH? tries to evaluate. Now there is a small complication here in the fact that the infix < operator
is actually seen as the argument to LENGTH? (just swap it in front of "zappo" mentally) so it has to
be evaluated, and it tries to determine less-than between its two apparent arguments "zappo" and 22 which
is an error.
To see it clearly try:
x: func [y][print [mold y type? y]]
x 2 < 3
==
true logic
It did not print "2 number".
Consequently, it turns out with all the evaluation proceeding simply left to right that parens are actually
less necessary more of the time than in languages with full hierarchies of precedence rules. For instance, in C
and C++ people tend to (wisely) parenthesize the heck of expressions because they aren't always sure if a cast
has a higher precedence than a bit wise xor etc.. In REBOL/core you only have to remember left --> right.
Q. How do I DO another
script and pass it arguments?
A. DO/ARGS
Q. Why isn't REBOL open
source?
A. Too early. Maybe at some point in the future.
Q. I'm getting way too much
mail to read right now. How do I unsubscribe from the REBOL users mailing list?
A. Send an empty message to list@REBOL.com with 'unsubscribe' as the only word
on the *SUBJECT* line.