REBOL  

The Internet Messaging LanguageTM

       
 

HOME

COMPANY
  Our Mission
  News Events
  Backgrounder
  Executive Bios
  To Contact Us

INTRODUCTION
  What Users Say
  In a Nutshell
  REBOL Features
  REBOL with a Cause
  What is Messaging?
  REBOL in Ten Steps

DOWNLOAD

LIBRARY
  Script Library
  User's Library

SUPPORT
  How-To
  Guides
  Feedback
  FAQ

JOBS

Download

 

Frequently-Asked Questions

  • I/O
    1. How do I get REBOL to not ask me for permission to write files each time I start it?
    2. How do I write filenames in REBOL?
    3. What high level directory operations are available?
    4. When I read a graphic or compressed file from a web page, it is not the right size. Why?
    5. How do I SEEK on a file so I don't have to read the entire file?
    6. There is no /BINARY refinement available for PRINT. How do I output a binary value to stdout?
  • CGI
    1. What do I have to do to get REBOL scripts to run directly as CGI's?
    2. How do I change a url-encoded string back to its normal human-readable characters?
    3. When REBOL is started with --cgi, should system/ports/output be opened with CR-LF as the default line ending?
  • Ports/Networking
    1. Why don't some series functions work on ports?
    2. How do I set up my proxy settings?
    3. Is it possible to get the last-modified date of a web page via REBOL?
    4. Does REBOL FTP support APPEND or RESTART commands?
    5. Sometimes REBOL has a network timeout error. How can I increase the network timeout value?
    6. How can I get started writing a protocol in REBOL?
    7. What is the SUB-PORT in the port object hierarchy?
    8. 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?
    9. How can I pick several characters at once from a port without using OPEN/LINES?
  • Built-in Documentation
    1. How do I find out what words are defined in the system?
    2. I notice when I try to assign the return value of WHAT or HELP I get an error message instead. Why?
    3. What if I want to write a function that does the same thing as WHAT but returns a value?
  • System
    1. What is in the system object?
    2. I find that when I type SOURCE SYSTEM, SOURCE REBOL, or PRINT SYSTEM, the computer will lock up. Why?
    3. REBOL won't find my %user.r file. Why?
    4. Why does REBOL take so long to start on some of my older computers?
  • Parse
    1. What are the basics of PARSE?
  • Datatypes
    1. What formats of binary numbers are supported?
    2. What IS a series?
    3. How do I make an array?
    4. How do I save a file with spaces in it?
    5. Are there any advantages to using lists verses blocks?
    6. What do I use a HASH! for?
  • Functions
    1. I noticed REBOL has built-in compression. How do I use it?
    2. Why doesn't REBOL have an ELSE statement?
    3. Why doesn't my block get reset each time? f: func [][ x: [] append x "a" ]
    4. What does the /LOCAL refinement in the function argument list do?
    5. How do I find out about a particular function of the system?
    6. How does the /COMPARE refinement work with the SORT function?
  • Enhancements
    1. Can REBOL launch other programs?
    2. Any plans to support IMAP? LDAP?
    3. How about ODBC?
  • Miscellaneous
    1. What do the REBOL version numbers mean?
    2. How do I refer to a global word if it has been redefined locally?
    3. How is context different from scope?
    4. How does BIND work?
    5. Can I use REBOL with XML?
    6. How does REBOL evaluation work?
    7. How do I DO another script and pass it arguments?
    8. Why isn't REBOL open source?
    9. 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.



 

A Platform-Independent Language for Practical Internet Solutions

Copyright © 1999 REBOL Technologies. All Rights Reserved. REBOL and The Internet Messaging Language are trademarks of REBOL Technologies.
Contact us at
info@rebol.com; Web problems: webmaster@rebol.com