< [[comparison] [<= > >= = <> minimum maximum] { Returns FALSE for all other values. An error will occur if the values are not of the same datatype. For string-based datatypes, the sorting order is used for comparison with character casing ignored (uppercase = lowercase). print "abc" < "abcd" print 15-June-1999 < 14-June-1999 print 1.2.3.4 < 4.3.2.1 print 1:30 < 2:00 } ] <= [[comparison] [< > >= = <> minimum maximum] { Returns FALSE for all other values. For string-based datatypes, the sorting order is used for comparison with character casing ignored (uppercase = lowercase). print "abc" <= "abd" print 14-June-1999 <= 15-June-1999 print 4.3.2.1 <= 1.2.3.4 print 1:23 <= 10:00 } ] <> [[comparison] [= == not-equal?] { String-based datatypes are considered equal when they are identical or differ only by character casing (uppercase = lowercase). Use == or find/match/case to compare strings by casing. print "abc" <> "abcd" print [1 2 4] <> [1 2 3] print 12-sep-98 <> 10:30 } ] = [[comparison] [<> == equal?] { String-based datatypes are considered equal when they are identical or differ only by character casing (uppercase = lowercase). Use == or find/match/case to compare strings by casing. print 123 = 123 print "abc" = "abc" print [1 2 3] = [1 2 4] print 15-June-1998 = 15-June-1999 print 1.2.3.4 = 1.2.3.0 print 1:23 = 1:23 } ] == [[comparison] [= <> strict-equal?] { Strict equality requires the values to not differ by datatype (so 1 would not be equal to 1.0) nor by character casing (so "abc" would not be equal to "ABC"). print 123 == 123 print "abc" == "ABC" } ] =? [[comparison] [= == same?] { This function returns true if two values are the same. That is, there is no way to distinguish between them. For instance, in the case of a string, they would occupy the same memory. a: "apple" b: a print a =? b b: tail a print a =? (head b) print "apple" =? "apple" } ] > [[comparison] [greater? < <= >= = <> minimum maximum] { Returns FALSE for all other values. The values must be of the same datatype or an error will occur. For string-based datatypes, the sorting order is used for comparison with character casing ignored (uppercase = lowercase). print "abc" > "abb" print 16-June-1999 > 15-June-1999 print 4.3.2.1 > 1.2.3.4 print 11:00 > 12:00 } ] >= [[comparison] [< <= > = <> minimum maximum] { Returns FALSE for all other values. The values must be of the same datatype or an error will occur. For string-based datatypes, the sorting order is used for comparison with character casing ignored (uppercase = lowercase). print "abc" >= "abb" print 16-June-1999 >= 15-June-1999 print 1.2.3.4 >= 4.3.2.1 print 11:00 >= 11:00 } ] equal? [[comparison] [= <> == =? strict-equal?] { String-based datatypes are equal when they are identical or differ only by character casing (uppercase = lowercase). print equal? 123 123 print equal? "abc" "abc" print equal? [1 2 3] [1 2 4] print equal? 15-June-1998 15-June-1999 print equal? 1.2.3.4 1.2.3.0 print equal? 1:23 1:23 } ] greater-or-equal? [[comparison] [>= < <= > = <> minimum maximum] { Returns FALSE for all other values. The values must be of the same datatype or an error will occur. For string-based datatypes, the sorting order is used for comparison with character casing ignored (uppercase = lowercase). print greater-or-equal? "abc" "abb" print greater-or-equal? 16-June-1999 15-June-1999 print greater-or-equal? 1.2.3.4 4.3.2.1 print greater-or-equal? 1:00 11:00 } ] greater? [[comparison] [> < <= >= = <> minimum maximum] { Returns FALSE for all other values. The values must be of the same datatype or an error will occur. For string-based datatypes, the sorting order is used for comparison with character casing ignored (uppercase = lowercase). print greater? "abc" "abb" print greater? 16-June-1999 15-June-1999 print greater? 4.3.2.1 1.2.3.4 print greater? 11:00 12:00 } ] lesser-or-equal? [[comparison] [<= < > >= = <> minimum maximum] { Returns FALSE for all other values. For string-based datatypes, the sorting order is used for comparison with character casing ignored (uppercase = lowercase). print lesser-or-equal? "abc" "abd" print lesser-or-equal? 14-June-1999 15-June-1999 print lesser-or-equal? 4.3.2.1 1.2.3.4 print lesser-or-equal? 1:23 10:00 } ] lesser? [[comparison] [<= > >= = <> minimum maximum] { Returns FALSE for all other values. The values must be of the same datatype, or an error will occur. For string-based datatypes, the sorting order is used for comparison with character casing ignored (uppercase = lowercase). print lesser? "abc" "abcd" print lesser? 15-June-1999 14-June-1999 print lesser? 1.2.3.4 4.3.2.1 print lesser? 1:30 2:00 } ] not-equal? [[comparison] [<> = == equal?] { String-based datatypes are considered equal when they are identical or differ only by character casing (uppercase = lowercase). print not-equal? "abc" "abcd" print not-equal? [1 2 4] [1 2 3] print not-equal? 12-sep-98 10:30 } ] same? [[comparison] [=? equal?] { Returns TRUE if the values are identical objects, not just in value. For example, a TRUE would be returned if two strings are the same string (occupy the same location in memory). Returns FALSE for all other values. a: "apple" b: a print same? a b print same? a "apple" } ] strict-equal? [[comparison] [== = <>] { Strict equality requires the values to not differ by datatype (so 1 would not be equal to 1.0) nor by character casing (so "abc" would not be equal to "ABC"). print strict-equal? 123 123 } ] strict-not-equal? [[comparison] [<> = ==] { A FALSE is returned if the values differ by datatype (so 1 would not be equal to 1.0) nor by character casing (so "abc" would not be equal to "ABC"). print strict-not-equal? 124 123 print strict-not-equal? 12-sep-98 10:30 } ] crlf [[constant] [tab newline] { Use CRLF as a shortcut to a #" ", the ASCII representations of a carriage return and line feed. Typically you should use NEWLINE in your REBOL scripts rather than CRLF. print ["To return" crlf "Or not to return"] } ] false [[constant] [true yes no on off] { Returns LOGIC value for not TRUE. print false print not true print 1 > 2 } ] newline [[constant] [tab crlf prin print] { Returns a string that, when printed, begins a new line. print ["start" newline "end"] } ] no [[constant] [true false on off yes] { Another word for LOGIC FALSE. print no print not no } ] none [[constant] [none? none!] { A single value that means NONE of something. print none print pick "abc" 4 str: "once upon a time" print find str "twice" blk: [values are here] print find blk 'there } ] off [[constant] [true false yes no on] { test: off print either test ["turned on" ] ["turned off"] } ] on [[constant] [true false yes no off] { test: on print either test ["turned on" ] ["turned off"] } ] pi [[constant] [arccosine arcsine arctangent cosine sine tangent] { Mathematical shortcut for 3.14159265358979. print pi print cosine/radians pi } ] tab [[constant] [crlf newline] { Use TAB as a shortcut to #"", the ASCII representation of a tab. print ["there be" tab "tabs" tab "amongst" tab tab "us."] } ] true [[constant] [false yes no on off] { Returns the LOGIC value for TRUE. Synonyms are YES, ON. if true [print "of course"] } ] yes [[constant] [true false on off no] { Another word for LOGIC TRUE. } ] zero [[constant] [zero? positive? negative?] { Returns a zero. a: zero set [a b] zero print zero? a print b } ] alias [[context] [set get] { Create an alias for a word. The alias will be identical in every respect to the aliased word (symbol comparison and value referencing). Be careful not to confuse alias with setting another word to the same value. The alias cannot be set if the word already appears anywhere within the script or has been used in any way prior to being aliased. alias 'print "stampa" do {stampa "MONDO Rebol"} } ] bind [[context] [use do func function] { Binds meaning to words in a block. That is, it gives words a context in which they can be interpreted. This allows blocks to be exchanged between different contexts, which permits their words to be understood. For instance a function may want to treat words in a global database as being local to that function. The second argument to BIND is a word from the context in which the block is to be bound. Normally, this is a word from the local context (e.g. one of the function arguments), but it can be a word from any context within the system. BIND will modify the block it is given. To avoid that, use the /COPY refinement. It will create a new block that is returned as the result. words: [a b c] fun: func [a b c][print bind words 'a] fun 1 2 3 fun "hi" "there" "fred" words: [a b c] object: make object! [ a: 1 b: 2 c: 3 prove: func [][print bind words 'a] ] object/prove settings: [start + duration] schedule: function [start] [duration] [ duration: 1:00 do bind settings 'start ] print schedule 10:30 } ] context [[context] [make] { This is a shortcut for MAKE OBJECT!. } ] get [[context] [set] { The argument to GET must be a word, so the argument must be quoted or extracted from a block. To get the value of a word residing in an object, use the IN function. value: 123 print get 'value print get second [the value here] print get in system/console 'prompt } ] in [[context] [set get] { Return the word from within another context. This function is normally used with SET and GET. set-console: func ['word value] [ set in system/console word value ] set-console prompt "==>" set-console result "-->" } ] set [[context] [get value? unset] { If the first argument is a block of words and the value is not a block, all of the words in the block will be set to the specified value. If the value is a block, then each of the words in the first block will be set to the respective values in the second block. If there are not enough values in the second block, the remaining words will be set to NONE The /ANY refinementallows words to be set any datatype including those such as UNSET! that are not normally allowed. This is useful in situations where all values must be handled. set 'test 1234 print test set [a b] 123 print a print b set [d e] [1 2] print d print e } ] unset [[context] [set] { Using UNSET, the word's current value will be lost. If a block is specified, all the words within the block will be unset. test: "a value" unset 'test print value? 'test } ] use [[context] [function! object!] { The first block contains a list of words which will be local to the second block. The second block will be evaluated and its results returned from the USE. total: 1234 nums: [123 321 456] use [total] [ total: 0 foreach n nums [total: total + n] print total ] print total } ] value? [[context] [unset? equal? strict-equal? same?] { Returns FALSE for all other values. The word can be passed as a literal or as the result of other operations. test: 1234 print value? 'test print value? second [test this] } ] all [[control logic] [and any] { Evaluates each expression in a block until one of the expressions returns NONE or FALSE, in which case a NONE is returned. No other expressions are evaluated beyond that point. Otherwise, the value of the last expression will be returned. a: 100 b: -100 if all [(a > b) (a > 10) (b < -3)] [print "all were true"] time: 10:30 if all [time > 10:00 time < 11:00] [print "time is now"] day: 10 time: 9:45 ready: all [day > 5 time < 10:00 time: 12:00] print time } ] any [[control logic] [all or and] { Evaluates each expression in a block until one of the expressions returns a value other than NONE or FALSE, in which case the value is returned. No other expressions are evaluated beyond that point. Otherwise, NONE will be returned. a: 100 b: -100 if any [(a > b) (a > 10) (b < -3)] [print "one was true"] time: 10:30 if any [time > 10:00 time < 11:00] [print "time is now"] day: 10 time: 9:45 ready: any [day > 5 time < 10:00 time: 12:00] print time } ] break [[control] [catch exit return loop repeat for forall foreach forever forskip while until] { The current loop is immediately terminated and evaluation resumes after the LOOP function. This function can be placed anywhere within the block being repeated, even within a sub block or function. repeat n 5 [ print n if n > 3 [break] ] } ] catch [[control] [throw do try] { CATCH and THROW go together. They provide a way to exit from a block without evaluating the rest of the block. To use it, provide CATCH with a block to evaluate. If within that block a THROW is evaluated, it will return from the CATCH at that point. The result of the CATCH will be whatever was passed as the argument to the THROW. When using multiple CATCH functions, provide them with a name using the /NAME refinement to identify which one will CATCH which THROW. write %file.txt "i am a happy little file with no real purpose" print catch [ if exists? %file.txt [throw "Doc found"] "Doc not found" ] } ] compose [[control] [reduce build-tag rejoin insert] { Constructs a block of values (output block) from another block of values (input block). Elements in the input block are placed in the output block with the exception of parenthesized elements. These elements are evaluated as expressions and their final return value placed in the output block. If the result is itself a block, then the elements of that block are inserted into the output block (in the same way as INSERT). To insert a block instead of its elements, place another block around it using the REDUCE function. The /DEEP refinement evaluates parenthesized elements within nested blocks. These elements are evaluated to the deepest level of nested blocks. probe compose [time (now/time) date (now/date)] block: compose [time: (now/time) date: (now/date)] probe block do block print time print date values: compose [2 + 2 2 / 2 (2 * 2) (2 - 1)] print form values sum1: 1 + 1 sum2: 2 + 2 sum3: 3 + 3 sum4: 4 + 4 sum5: 5 + 5 sum6: 6 + 6 print mold compose [(sum1) sum2 ([sum3 sum4]) [sum5 sum6]] print mold compose/deep [[(sum1) sum2] [sum3 [[(sum4) sum5] (sum6)]]] } ] disarm [[control] [error! trace] { DISARM allows access to the values of an error object. If the error is not disarmed, it will occur again immediately. probe disarm try [1 + "x"] } ] dispatch [[control port] [] { ??? } ] do [[control port] [load reduce loop repeat] { Accepts a block, or LOADs a string, file, or URL into a block, then evaluates the expressions of the block. Files and URLs must have a valid REBOL header. Elements are evaluated left to right. When an element encountered is a function requiring arguments, the function's arguments are first evaluated then passed to the function before it is evaluated. The value of final evaluation is returned. The /ARGS refinement allows you to pass arguments to another script and is used with a file, or URL. Arguments passed with /ARGS are stored in system/script/args within the context of the loaded script. The /NEXT refinement returns a block consisting of two elements. The first element is the evaluated return of the first expression encountered. The second element is the original block with the current index placed after the last evaluated expression. print do "1 + 2" do "repeat n 3 [print n]" do [print "doing"] print do [1 + 2] blk: [ [print "test"] [loop 3 [print "loop"]] ] do second blk do first blk blk: [ [1 + 2] [3 * 4] [6 / 3] ] while [not empty? blk][ set [value blk] do/next blk print value ] } ] does [[control] [] { ??? } ] either [[control] [if pick] { EITHER is identical to the if-else style comparison in other languages. In addition, EITHER returns the result of the block that it evaluates. grade: 72 either grade > 60 [ print "Passing Grade!" ][ print "Failing Grade!" ] print either grade > 60 ["Passing"]["Failing"] } ] exit [[control] [return catch break] { Use QUIT to exit the interpreter. test-str: make function! [str] [ if not string? str [exit] print str ] test-str 10 test-str "right" } ] for [[control] [forall foreach forever forskip] { The first argument is used as a local variable to keep track of the current value. It is initially set to the START value and after each evaluation of the block the BUMP value is added to it until the END value is reached (inclusive). for num 0 30 10 [ print num ] for num 4 -37 -15 [ print num ] } ] forall [[control] [for foreach forskip] { Prior to evaluation, the WORD argument must be set to the desired starting position within the series (normally the head, but any position is valid). After each evaluation of the block, the word will be advanced to the next position within the series. cities: ["Eureka" "Ukiah" "Santa Rosa" "Mendocino"] forall cities [print first cities] chars: "abcdef" forall chars [print first chars] } ] foreach [[control] [for forall forskip] { For each evaluation of the block, the word will be set to the first value in the series. The WORDS argument can be a single word or a block of words. cities: ["Eureka" "Ukiah" "Santa Rosa" "Mendocino"] foreach city cities [print city] chars: "abcdef" foreach char chars [print char] } ] forever [[control] [loop while until] { Evaluates a block continuously, or until a break or error condition is met. forever [ if (random 10) > 5 [break] ] } ] forskip [[control] [for forall foreach skip] { Prior to evaluation, the word must be set to the desired starting position within the series (normally the head, but any position is valid). After each evaluation of the block, the word's position in the series is changed by skipping the number of values specified by the second argument (see the SKIP function). areacodes: [ "Ukiah" 707 "San Francisco" 415 "Sacramento" 916 ] forskip areacodes 2 [ print [ first areacodes "area code is" second areacodes] ] } ] func [[control] [function make function! function? return exit] { The spec is a block that specifies the interface to the function. It can begin with an optional string which will be printed when asking for HELP on the function. That is followed by the words that specify the arguments to the function. Each of these words may include an optional block of datatypes. These specify the valid datatypes for the argument. That may be followed by a comment string which describes the argument in more detail. The argument words may also specify a few variations on the way the argument will be evaluated. The most common is 'word which indicates that a word is expected that should not be evaluated (the function wants its name, not its value). A :word may also be given which will get the value of the argument, but not perform full evaluation. To add refinements to a function supply a slash (/) in front of an argument's word. Within the function the refinement can be tested to determine if the refinement was present. If a refinement is followed by more arguments, they will be associated with that refinement and are only evaluated when the refinement is present. Local variables are specified after a /LOCAL refinement. A function returns the last expression it evaluated. You can also use RETURN and EXIT to exit the function. A RETURN is given a value to return. EXIT returns no value. sum: func [a b] [a + b] print sum 123 321 sum: func [nums [block!] /average /local total] [ total: 0 foreach num nums [total: total + num] either average [total / (length? nums)][total] ] print sum [123 321 456 800] print sum/average [123 321 456 800] print-word: func ['word] [print form word] print-word testing } ] function [[control] [func make use function! function? return exit] { FUNCTION is identical to FUNC but includes a block in which you can name words considered LOCAL to the function. average: function [block] [total] [ total: 0 foreach number block [total: number + total] total / (length? block) ] print average [1 10 12.34] } ] halt [[control] [quit break exit catch] { Useful for program debugging. div: 10 if error? try [100 / div] [ print "math error" halt ] } ] has [[control] [] { Defines a function that consists of local variables only. This is a shortcut for FUNC and FUNCTION. For example: ask-name: has [name] [ name: ask "What is your name?" print ["Hello" name] ] ask-name The example above is a shortcut for: ask-name: func [/local name] [...] } ] if [[control] [either switch select] { Skip the block if the value is FALSE. To select an alternate result (else) use the EITHER function. IF returns the value of the block it evaluated or FALSE otherwise. age: 4 if age > 3 [print "wine is ready"] print if age > 2 ["ready"] print if age < 2 ["not ready"] } ] launch [[control] [] { ??? } ] loop [[control] [break repeat for while until] { Returns the value of the final execution of the block. The BREAK function can be used to stop the loop at any time (but no value is returned). The REPEAT function is similar to LOOP, except that it keeps track of the current loop count. loop 40 [prin "*"] print "" } ] next [[control] [back first head tail head? tail?] { If the series is at its tail, it will remain at its tail. NEXT will not go past the tail, nor will it wrap to the head. print next "ABCDE" print next next "ABCDE" print next [1 2 3 4] str: "REBOL" loop length? str [ print str str: next str ] blk: [red green blue] loop length? blk [ probe blk blk: next blk ] } ] quit [[control] [halt exit] { Releases all resources back to the system. Shortcut: Q. Use EXIT to exit a function without returning a value. time: 10:00 if time > 12:00 [ print "time for lunch" quit ] } ] reduce [[control] [compose do foreach] { When given a block, evaluates each of its expressions and returns a block with all of the results. Very useful for composing blocks of values. values: reduce [1 + 2 3 + 4] print first values print second values } ] repeat [[control] [loop for forall foreach forskip while until] { If the value is an integer, the word is used to keep track of the current loop count, which begins at one and continues up to and including the integer value given. If the value is a series, then the word holds the first value of each element of the series (see FOREACH). Returns the value of the final evaluation. The BREAK function can be used to stop the loop at any time (but no value is returned). The word is local to the block. repeat num 5 [print num] } ] return [[control] [break exit catch] { Exits the current function immediately, returning a value as the result of the function. To return no value, use the EXIT function. fun: make function! [this-time] [ return either this-time >= 12:00 ["after noon"][ "before noon"] ] print fun 9:00 print fun 18:00 } ] secure [[control port] [open read write] { Controls file and network access using a dialect to specify security. You can set different security for networking, files, and specific files and directories. Levels of security offered are ALLOW, ASK, THROW, and QUIT. ALLOW removes all READ and/or WRITE restrictions. ASK restricts immediate READ and/or WRITE access and prompts the user for each access attempt requiring approval before the operation may be completed. THROW denies READ and/or WRITE access throwing an error when a restricted access attempt is made. QUIT denies READ and/or WRITE access and quits the script when restricted access is attempted. SECURE's argument may be a security setting used as a global setting, or a block containing a detailed breakdown of network and file access permissions. Access to specific files and directories is controlled using a specific file, or directory name in place of FILE. The previous secure settings are returned as a block. secure [ net allow file [ask write allow read] %. allow %.. [quit write] ] } ] switch [[control series] [select find] { Switch also returns the value of the block it executes. The cases can be any datatype. If none of the other cases match, use the /DEFAULT refinement to specify a default case. switch 22 [ 11 [print "here"] 22 [print "there"] ] person: 'mom switch person [ ; words dad [print "here"] mom [print "there"] kid [print "everywhere"] ] file: %user.r switch file [ %user.r [print "here"] %rebol.r [print "everywhere"] %file.r [print "there"] ] url: ftp://ftp.rebol.org switch url [ http://www.rebol.com [print "here"] http://www.cnet.com [print "there"] ftp://ftp.rebol.org [print "everywhere"] ] html-tag: print switch html-tag [ <PRE> ["Preformatted text"] <TITLE> ["Page title"] <LI> ["Bulleted list item"] ] time: 12:30 switch time [ 8:00 [send wendy@domain.dom "Hey, get up"] 12:30 [send cindy@dom.dom "Join me for lunch."] 16:00 [send group@every.dom "Dinner anyone?"] ] car: pick [Ford Chevy Dodge] random 3 print switch car [ Ford [351 * 1.4] Chevy [454 * 5.3] Dodge [154 * 3.5] ] } ] throw [[control] [catch return exit] { CATCH and THROW go together. They provide a method of exiting from a block without evaluating the rest of the block. To use it, provide CATCH with a block to evaluate. If within that block a THROW is evaluated, the script will return from the CATCH at that point. The result of the CATCH will be the value that was passed as the argument to the THROW. When using multiple CATCH functions, provide them with a name to identify which one will CATCH which THROW. print catch [ if exists? %file.txt [throw "Doc file!"] ] } ] throw-on-error [[control] [] { ??? } ] try [[control] [error? disarm do] { TRY provides a useful means of capturing errors and handling them within a script. For instance, use TRY to test an expression that could fail and stop the script. TRY returns an error value if an error happened, otherwise it returns the normal result of the block. if error? try [1 + "x"] [print "Did not work."] if error? try [load "$10,20,30"] [print "No good"] } ] until [[control] [while repeat for] { Evaluates a block until the block returns a TRUE value (that is, the last expression in the block is TRUE). str: "string" until [ print str tail? str: next str ] } ] wait [[control port] [time! date!] { If the value is a TIME, delay for that period. If the value is a DATE/TIME, wait until that DATE/TIME. If the value is an INTEGER or DECIMAL, wait that number of seconds. If the value is a PORT, wait for an event from that port. If a block is specified, wait for any of the times or ports to occur. Return the port that caused the wait to complete or return NONE if the timeout occurred. print now/time wait 1 print now/time wait 0:00:01 print now/time } ] while [[control] [loop repeat for until] { BREAK can be used to escape from the block at any point. str: "string" while [not tail? str: next str] [ print ["length of" str "is" length? str] ] } ] ?? [[debug] [] { Handy for printing the value of a variable while debugging. } ] probe [[debug help] [mold print] { Probe is very useful for debugging. Insert it anywhere a value is being passed and it will display the value without interfering with the code. probe ["red" "green" "blue"] if probe now/time > 12:00 [print "now"] } ] trace [[debug help] [echo probe] { Used for debugging a script. TRACE ON turns it on. TRACE OFF turns it off. To limit the amount of output selective place trace around the parts of the script that need it. TRACE/NET allows watching what the network protocols are doing. } ] ? [[help] [help what source] { Synonym for HELP. ? switch } ] about [[help] [license usage help system] " about^/^/" ] comment [[help] [do] { This function can be used to add comments to a script or to remove a block from evaluation. Note that this function is only effective in evaluated code and has no effect in data blocks. That is, within a data block comments will appear as data. In many cases, using COMMENT is not necessary. Placing braces around any expression will prevent if from being evaluated (so long as it is not part of another expression). comment "This is a comment." comment [print "As a comment, this is not printed"] } ] feedback [[help] [] { ??? } ] help [[help] [? what] " help quit^/^/" ] license [[help] [about] " license^/^/" ] source [[help] [help ?] { Useful for learning how mezzanine (higher level) functions are defined. If the function is a native, SOURCE returns the function's specification block. source copy source source } ] usage [[help] [help ?] { This includes command line options and examples. usage } ] what [[help] [help ?] "" ] * [[math] [/ // multiply divide] { The datatype of the second value may be restricted to INTEGER or DECIMAL, depending on the datatype of the first value (e.g. the first value is a time). print 123 * 10 print 12.3 * 10 print 3:20 * 3 } ] ** [[math] [power exp log-2 log-10 log-e] { This is the operator for the POWER function. print 10 ** 2 print 12.345 ** 5 } ] + [[math] [- add subtract] { When adding values of different datatypes, the values must be compatible. print 123 + 1 print 12:00 + 11:00 print 31-Dec-1999 + 1 print 1.2.3.4 + 4.3.2.1 } ] - [[math] [+ add subtract negate absolute] { If used with only a single value, it negates the value (unary minus). When subtracting values of different datatypes, the values must be compatible. print 123 - 1 print -123 ; a negative number print - 123 ; negating a positive number (unary) print 12:00 - 11:00 print 1-Jan-2000 - 1 print 1.2.3.4 - 1.0.3.0 } ] / [[math] [* // divide] { An error will occur if the second value is zero. When dividing values of different datatypes they must be compatible. print 123 / 10 print 12.3 / 10 print 1:00 / 60 } ] // [[math] [* / remainder] { Returns the value of the remainder after the first number is divided by the second. If the second number is zero, an error will occur. print 123 // 10 print 25:32 // 24:00 } ] abs [[math] [] { A synonym for absolue. } ] absolute [[math] [- negate] { Returns a positive value equal in magnitude. print absolute -123 print absolute -1:23 } ] add [[math] [+ - subtract] { When adding values of different datatypes, the values must be compatible. print add 123 1 print add 1.2.3.4 4.3.2.1 print add 3:00 -4:00 print add 31-Dec-1999 1 } ] and [[math logic] [or all not xor logic? integer?] { For LOGIC values, both values must be TRUE to return TRUE, otherwise a FALSE is returned. For integers, each bit is separately affected (a numerical AND). All arguments are fully evaluated. print true and true print true and false print (10 < 20) and (20 > 15) print 123 and 1 print 1.2.3.4 and 255.0.255.0 } ] arccosine [[math] [arcsine arctangent cosine exp log-10 log-2 log-e pi power sine square-root tangent] { Inverse function to the cosine. print arccosine .5 } ] arcsine [[math] [arccosine arctangent cosine exp log-10 log-2 log-e pi power sine square-root tangent] { Inverse function to the sine. print arcsine .5 } ] arctangent [[math] [arccosine arcsine cosine exp log-10 log-2 log-e pi power sine square-root tangent] { Inverse function to the tangent. print arctangent .22 } ] complement [[math logic] [negate] { Used for bitmasking of integer numbers and inverting bitsets (charsets). print complement 0 print complement -1 chars: complement charset "ther " print find "there it goes" chars } ] cosine [[math] [arccosine arcsine arctangent pi sine tangent] { Ratio between the length of the adjacent side to the length of the hypotenuse of a right triangle. print cosine 90 print (cosine 45) = (sine 45) print cosine/radians pi } ] divide [[math] [* / // multiply] { If the second value is zero, an error will occur. When dividing values of different datatypes, they must be compatible. print divide 123.1 12 print divide 10:00 4 } ] even? [[math] [odd? zero?] { print even? 100 print even? 7 } ] exp [[math] [log-10 log-2 log-e power] " print exp 3^/^/" ] log-10 [[math] [exp log-2 log-e power] " print log-10 1234^/^/" ] log-2 [[math] [exp log-10 log-e power] " print log-2 1234^/^/" ] log-e [[math] [exp log-10 log-2 power] { print log-e 1234 print exp log-e 1234 } ] max [[math] [] { ??? } ] maximum [[math] [< > minimum] { print maximum "abc" "abd" print maximum 12:00 11:00 } ] min [[math] [] { ??? } ] minimum [[math] [< > maximum] { print maximum "abc" "abd" print maximum 12:00 11:00 } ] multiply [[math] [* / // divide] { The datatype of the second value may be restricted to INTEGER or DECIMAL, depending on the datatype of the first value (e.g. the first value is a time). print multiply 123 10 print multiply 3:20 3 print multiply 0:01 60 } ] negate [[math] [+ - positive? negative?] " print negate 123^/ print negate 123.45^/^/" ] negative? [[math] [positive?] { Returns FALSE for all other values. print negative? -50 print negative? 50 } ] not [[math logic] [and or xor] { Function returns TRUE if the value is FALSE, and FALSE if it is TRUE. To bitwise complement an INTEGER, use the COMPLEMENT function. print not true print not (10 = 1) } ] odd? [[math] [even?] { print odd? 3 print odd? 100 print odd? 0 } ] or [[math logic] [and not xor] { An infix-operator. For LOGIC values, both must be FALSE to return FALSE; otherwise a TRUE is returned. For integers, each bit is separately affected. Because it is an infix operator, OR must be between the two values. print true or false print (10 > 20) or (20 < 100) print 122 or 1 print 1.2.3.4 or 255.255.255.0 } ] positive? [[math] [negative?] { Returns FALSE for all other values. print positive? 50 print positive? -50 } ] power [[math] [** exp log-10 log-2 log-e] { print power 10 2 print power 12.3 5 } ] random [[math logic series] [now] { The value passed can be used to restrict the range of the random result. For integers random begins at one, not zero, and is inclusive of the value given. (This conforms to the indexing style used for all series datatypes, allowing random to be used directly with functions like PICK.) To initialize the random number generator to a random state, you can seed it with the current time. loop 4 [print random 10] lunch: ["Italian" "French" "Japanese" "American"] print pick lunch random 4 loop 3 [print random true] loop 5 [print random 1:00:00] random/seed now } ] remainder [[math] [// * /] { If the second number is zero, an error will occur. print remainder 123 10 print remainder 10 10 print remainder 10.2 10 } ] sine [[math] [arccosine arcsine arctangent cosine pi tangent] { Ratio between the length of the opposite side to the length of the hypotenuse of a right triangle. print sine 90 print (sine 45) = (cosine 45) print sine/radians pi } ] square-root [[math] [exp log-10 log-2 log-e power] " print square-root 2^/^/" ] subtract [[math] [- + add absolute] { When subtracting values of different datatypes the values must be compatible. print subtract 123 1 print subtract 1.2.3.4 1.0.3.0 print subtract 12:00 11:00 print subtract 1-Jan-2000 1 } ] tangent [[math] [arccosine arcsine arctangent cosine pi tangent] { Ratio between the length of the opposite side to the length of the adjacent side of a right triangle. print tangent 30 print tangent/radians 2 * pi } ] xor [[math logic] [and or not] { For integers, each bit is exclusively-or'd. For logic values, this is the same as the not-equal function. print 122 xor 1 print true xor false print false xor false print 1.2.3.4 xor 1.0.0.0 } ] zero? [[math] [positive? negative?] { Check the value of a word is zero. print zero? 50 print zero? 0 } ] system [[object] [object! object?] { The system object used by the REBOL interpreter. Most of this is not for user modification. For advanced discussion on system, see the Users Guide. print system/version print system/product } ] ask [[port] [confirm input prin] { Provides a common prompting function that is the same as a PRIN followed by an INPUT. The resulting input will have spaces trimmed from its head and tail. The /HIDE refinement hides input with "*" characters. print ask "Your name, please? " } ] change-dir [[port] [make-dir what-dir list-dir] { Changes the value of system/script/path. This value is used for file-related operations. Any file path that does not begin with a slash (/) will be relative to the path in system/script/path. When a script file is executed using the DO native, the path will automatically be set to the directory containing the path. When REBOL starts, it is set to the current directory where REBOL is started. current: what-dir make-dir %./rebol-temp/ probe current change-dir %./rebol-temp/ probe what-dir change-dir current delete %./rebol-temp/ probe what-dir } ] clean-path [[port string] [split-path change-dir dir? list-dir] { Rebuilds a directory, or URL path after following parent (..) and current (.) path indicators. probe clean-path %com/www/../graphics/image.jpg probe clean-path http://www.rebol.com/www/../index.html messy-path: %/rebol/scripts/neat-stuff/../../experiments/./tests neat-path: clean-path messy-path probe neat-path } ] close [[port] [open load do send] { Closes a port opened with the OPEN function. Any changes to the port data that have been buffered will be written. rebol-port: open http://www.REBOL.com if find rebol-port "REBOL" [print "You did it!"] close rebol-port } ] confirm [[port] [ask input prin] { This function provides a method of prompting the user for a TRUE ("y" or "yes") or FALSE ("n" or "no") response. Alternate responses can be identified with the /WITH refinement. confirm "Answer: 14. Y or N? " confirm/with "Use A or B? " ["A" "B"] } ] connected? [[port] [] { ??? } ] delete [[port] [exists?] { Deletes the file or URL object that is specified. If the file or URL refers to an empty directory, then the directory will be deleted. write %delete-test.r "This file is no longer needed." delete %delete-test.r } ] dir? [[port] [make-dir modified? exists?] { Returns FALSE if it is not a directory. print dir? %file.txt print dir? %. } ] dirize [[port string] [] { Convert a file name to a directory name. For example: probe dirize %dir } ] echo [[port] [print trace] { Write output to a file in addition to the user console. The previous contents of a file will be overwritten. The echo can be stopped with ECHO NONE or by starting another ECHO. echo %helloworld.txt print "Hello World!" echo none } ] exists-via? [[port] [] { ??? } ] exists? [[port] [read write delete modified? size?] { Returns FALSE if the file does not exist. print exists? %file.txt print exists? %doc.r } ] info? [[port] [exists? dir? modified? size?] { The information is returned within an object that has SIZE, DATE, and TYPE words. These can be accessed in the same manner as other objects. info: info? %file.txt print info/size print info/date } ] input [[port] [input? ask confirm] { Returns a string from the standard input device (normally the keyboard, but can also be a file or an interactive shell). The string does not include the new-line character used to terminate it. The /HIDE refinement hides input with "*" characters. prin "Enter a name: " name: input print [name "is" length? name "characters long"] } ] input? [[port] [input] { INPUT? can be used to determine if input is waiting to be read from the standard input device. When it returns TRUE, input is waiting to be read (with INPUT). print input? if input? [name: input] } ] list-dir [[port] [change-dir make-dir what-dir read] { Lists the files and directories of the specified path in a sorted multi-column output. If no path is specified, the directory specified in system/script/path is listed. Directory names are followed by a slash (/) in the output listing. To obtain a block of files for a directory, use the READ function. list-dir files: read %. print length? files } ] load [[port series] [read save do] { Reads and converts external data for use by the REBOL language. Typically, a LOAD is done on a text string or a file consisting of text. The string is searched for a REBOL header, and if found, it will be evaluated first. If the load results in a single value, it will be returned. If it results in a block, the block will be returned. No evaluation of the block will be done; however, words in the block will be bound to the global context. If the header is desired, use the /HEADER option to return it as the first element in the block. The /NEXT refinement returns a block consisting of two elements. The first element is the first value loaded in the series. The second element is the original series with the current index just past the LOADed value. data: load "11 22 33 44" print third data set [value data] load/next data print value print data } ] load-thru [[port] [] { ??? } ] make-dir [[port] [change-dir what-dir list-dir delete] { Creates a new directory at the specified location. This operation can be performed for files or FTP URLs. make-dir %New-Dir/ delete %New-Dir/ } ] modified? [[port] [exists?] { Returns NONE if the file does not exist. print modified? %file.txt } ] open [[port] [close load do send] { Opens a port for I/O operations. The value returned from OPEN can be used to examine or modify the data associated with the port. The argument must be a fully-specified port specification, an abbreviated port specification such as a file path or URL, or a block which is executed to modify a copy of the default port specification. autos: open/new %autos.txt insert autos "Ford" insert tail autos " Chevy" close autos print read %autos.txt } ] prin [[port] [print] { No line termination is used, so the next value printed will appear on the same line. If the value is a block, each of its values will be evaluated first then printed. prin "The value is " prin [1 + 2] prin ["The time is" now/time] } ] print [[port] [prin] { If the value is a block, each of its values will be evaluated first, then printed. print 1234 print ["The time is" now/time] } ] query [[port] [open update] { Its argument is an unopened port specification. The size, date and status fields in the port specification will be updated with the appropriate information if the query succeeds. } ] read [[port] [write open close load save file! url! port!] { Using READ is the simplest way to get information from a file or URL. This is a higher level port operation that opens a port, reads some or all of the data, then closes the port and returns the data that was read. When used on a file, or URL, the contents of the file, or URL are returned as a string. The /BINARY refinement forces READ to do a binary read. When used on a text file, line terminators will not be converted. The /STRING refinement translates line terminators to the operating system's line terminator. This behavior is default. The /DIRECT refinement reads without buffering, useful for reading files too large to contain in memory. The /LINES refinement returns read content as a series of lines. One line is created for each line terminator found in the read data. The /PART refinement reads the specified number of elements from the file, URL, or port. Reading a file or URL will read the specified number of characters. Used with /LINES, it reads a specified number of lines. The /WITH refinement converts characters, or strings, specified into line terminators. See the User's Guide for more detailed explanation of using READ and its refinements. write %rebol-test-file.r "text file" print read %rebol-test-file.r write %rebol-test-file.r [ {A learned blockhead is a greater man than an ignorant blockhead. -- Rooseveldt Franklin} ] probe first read/lines %rebol-test-file.r probe pick (read/lines %rebol-test-file.r) 3 probe read/part %rebol-test-file.r 9 probe read/with %rebol-test-file.r "blockhead" } ] read-io [[port] [] { ??? } ] read-net [[port] [] { ??? } ] read-thru [[port] [] { ??? } ] read-via [[port] [] { ??? } ] rename [[port] [delete list-dir what-dir] { This function cannot be used to move a file from one directory to another. write %testfile now rename %testfile %remove.me delete %remove.me } ] resend [[port] [send] { Resends an email message to the specified email. Resent emails are in no way altered leaving even the original "To:", "From:", and other fields intact. Messages resent must be passed to RESEND as a single string value containing the email. ;resend luke@rebol.com me@here.dom some-message } ] save [[port] [load send] { Performs the appropriate conversion and formatting to preserve datatypes. For instance, if the value is a REBOL block, it will be saved as a REBOL script that, when loaded, will be identical. save %date.r now print read %date.r date: load %date.r print date save %data.r reduce ["Data" 1234 %filename now/time] print read %data.r probe load %data.r } ] script? [[port] [parse-header] { If the header is found, the script string will be returned as of that point. If not found, then NONE is returned. print either script? %file.txt ["found"]["not found"] } ] send [[port] [resend save] { The first argument can be an email address or block of addresses. The value sent can be any REBOL datatype, but it will be converted to text prior to sending. For email, the message header will be constructed from the default header, unless the /HEADER refinement and a header object is provided. The /ONLY refinement will use bulk email, sending a single message to multiple email addresses. Before you can use this function you must setup your network configuration with SET-NET. This can be done interactively by running the SET-USER function defined in rebol.r. send luke@rebol.com "Testing REBOL Function Summary" header: make system/standard/email [ To: [luke@rebol.com] From: [user@world.dom] Subject: "Message with a header" Organization: "REBOL Alliance" ] send/header luke@rebol.com trim { This is a longer message that also contains a header. } header } ] set-net [[port util] [] { See the manual for a detailed description of this function. The block contains a series of values used for network settings. Use SET-NET to establish the network settings REBOL will use to access your LAN, or WAN. The first value is your email address and it is used when sending email and connecting to FTP. This value is stored in the REBOL system object at: SYSTEM/USER/EMAIL The second value is your SMTP (outgoing email) server name or address. This is stored in the REBOL system object at: SYSTEM/SCHEMES/DEFAULT/HOST The third value is an optional POP (incoming email) server name or address. This is stored at: SYSTEM/SCHEMES/POP/HOST The fourth value is an optional proxy server name or address. See the manual for a complete description. This is at: SYSTEM/SCHEMES/DEFAULT/PROXY/HOST The fifth value is an optional proxy port number. This is at: SYSTEM/SCHEMES/DEFAULT/PROXY/PORT-ID The sixth value is an optional proxy protocol. It can be socks, socks5, socks4, generic, or none. This is at: SYSTEM/SCHEMES/DEFAULT/PROXY/TYPE This is a helper function. You can always set any of the protocols directly. set-net [ user@domain.name smtp.domain.name ] set-net [ user@domain.name smtp.domain.name pop.domain.name proxy.domain.name 1080 socks ] } ] size? [[port] [modified? exists?] { If the file or URL is a directory, it returns the number of entries in the directory. print size? %file.txt } ] split-path [[port string] [clean-path] { Returns a block consisting of two elements, the path and the file. Can be used on URLs and files alike. probe split-path %tests/math/add.r set [path file] split-path http://www.rebol.com/graphics/logo.gif print path print file } ] suffix? [[port string] [] { ??? } ] update [[port] [read write insert remove query] { Updates the input or output of a port. If input is expected, the port is checked for more input. If output is pending then that output is written. out: open/new %trash.me insert out "this is a test" update out insert out "this is just a test" close out } ] what-dir [[port] [change-dir make-dir list-dir] { Returns the value of system/script/path, the default directory for file operations. print what-dir } ] write [[port] [read open close load save file! url! form] { WRITE is typically used to write a file to disk, but many other operations, such as writing data to URLs and ports, are possible. Normally a string or binary value is provided to this function, but other types of data such as a number or a time can be written. They will be converted to text. The /BINARY refinement will write out data as its exact representation. This is good for writing image, sound and other binary data. The /STRING refinement translates line terminators to the operating system's line terminator. This behavior is default. The /APPEND refinement is useful logging purposes, as it won't overwrite existing data. The /LINES refinement can take a block of values and will write each value to a line. By default, WRITE will write the block of values as a concatonated string of formed values. The /PART refinement will read the specified number of elements from the data being written. The /WITH refinement converts characters, or strings, specified into line terminators. See the User's Guide for more detailed explanation of using READ and its refinements. write %junkme.txt "This is a junk file." write %datetime.txt now write/binary %data compress "this is compressed data" write %rebol-test-file.r "some text" print read %rebol-test-file.r write/append %rebol-test-file.r "some more text" print read %rebol-test-file.r write %rebol-test-file.r reduce ["the time is:" form now/time] print read %rebol-test-file.r write/lines %rebol-test-file.r reduce ["time is:" form now/time] print read %rebol-test-file.r write/part %rebol-test-file.r "this is the day!" 7 print read %rebol-test-file.r } ] write-io [[port] [] { ??? } ] append [[series modify] [insert change remove] { Works on any type of series, including strings and blocks. Returns the series at its head. /ONLY forces a block to be inserted as a block element (works only if the first argument is a block). string: copy "hello" probe append string " there" file: copy %file probe append file ".txt" url: copy http:// probe append url "www.rebol.com" block: copy [1 2 3 4] probe append block [5 6] probe append/only block [a block] } ] array [[series] [make] { Supplying an single integer as the argument will create an array of a single dimension. To create an array of multiple dimensions, provide a block of integers. Each integer specifies the size of that dimension of the array. Normally the elements of the array will be initialized to NONE. However, other initialization values (such as zero) can be specified with the /INITIAL refinement. Arrays are rarely used in REBOL, but are provided for those familiar with other languages. In REBOL it is better practice to use series functions rather than array accesses. numbers: array 5 ; makes an array of 5 elements image: array [10 25] ; makes an array of 10 rows of 25 values xyz: array [10 25 5] ; makes a three-dimensional array repeat index 5 [poke numbers index index] print numbers numbers/3: 12345 image/4/20: http://www/colors.jpg xyz/10/5/2: 123.200.200 numbers: array/initial 5 10 print numbers } ] at [[series] [skip pick head tail] { Provides a simple way to index into a series. AT returns the series at the new index point. Note that the operation is relative to the current position within the series. numbers: [11 22 33] print at numbers 2 words: [grand grape great good] print first at words 2 remove at words 2 insert at words 3 [super] probe words } ] back [[series] [next last head tail head? tail?] { If the series is at its head, it will remain at its head. BACK will not go past the head, nor will it wrap to the tail. print back tail "abcd" str: tail "time" until [ str: back str print str head? str ] blk: tail [1 2 3 4] until [ blk: back blk print first blk head? blk ] } ] change [[series modify] [append clear insert remove sort] { If the second argument is a simple value, it will replace the value at the current position in the first series. If the second argument is a series compatible with the first (block or string-based datatype), all of its values will replace those of the first argument or series. The /PART refinement changes a specified number of elements within the target series. For the convenience of cascading multiple changes the CHANGE function returns the series position just past the change. probe head change "bog" "d" probe head change [123 "test"] "the" probe head change/dup "abc" "->" 5 probe head change/part "abcde" "1234" 2 probe head change [1 4 5] [1 2 3] title: copy "how it REBOL" change title "N" probe title change find title "t" "s" probe title blk: copy ["now" 12:34 "REBOL"] change next blk "is" probe blk probe head change/only [1 4 5] [1 2 3] probe head change/only [1 4 5] [[1 2 3]] string: copy "crush those grapes" change/part string "eat" find/tail string "crush" probe string } ] clear [[series modify] [remove append change insert sort] { CLEAR is similar to REMOVE but removes through the end of the series rather than just a single value. str: copy "with all things considered" clear skip str 8 print str str: copy "get there quickly" clear find str "qui" print str } ] copy [[series] [change clear insert make remove] { Be sure to use COPY on any string or block literal values in your code if you expect to modify them. For series, the /PART refinement will copy a given number of values (specified as either a count or as an ending series position). str: copy "with all things considered" print str strings: copy ["how" "flies"] print strings insert next strings "time" print strings } ] empty? [[series] [tail? none? found?] { This is a synonym for TAIL? The check is made relative to the current location in the series. print empty? [] print empty? [1] } ] fifth [[series] [pick first second third fourth] { An error will occur if no value is found. Use the PICK function to avoid this error. print fifth "REBOL" print fifth [11 22 33 44 55 66] } ] find [[series] [select pick] { Returns NONE if the value was not found. Otherwise, returns a position in the series where the value was found. Many refinements to this function are available. /TAIL indicates that the position just past the match should be returned. The /MATCH refinement can be used to perform a character by character match of the input value to the series. The position just past the match is returned. Wildcards can be specified with /ANY and case sensitive comparisons can be made with /CASE. The /ONLY refinement applies to block values and is ignored for strings. The /LAST refinement causes FIND to search from the TAIL of the series toward the HEAD. /REVERSE searches backwards from the current position toward the head. print find "here and now" "and" print find/tail "here and now" "and" print find [12:30 123 c@d.com] 123 print find [1 2 3 4] 5 print find/match "here and now" "here" print find/match "now and here" "here" print find [1 2 3 4 3 2 1] 2 print find/last %file.fred.txt "." print find/last [1 2 3 4 3 2 1] 2 print find/any "here is a string" "s?r" } ] first [[series] [pick second third fourth fifth] { An error will occur if no value is found. Use the PICK function to avoid this error. print first "REBOL" print first [11 22 33 44 55 66] print first 1:30 print first 199.4.80.1 print first 12:34:56.78 } ] found? [[series logic] [find pick] { Returns FALSE for all other values. Not usually required because most conditional function will accept a NONE as FALSE and all other values as TRUE. if found? find carl@rebol.com ".com" [print "found it"] } ] fourth [[series] [first second third fifth pick] { An error will occur if no value is found. Use the PICK function to avoid this error. print fourth "REBOL" print fourth [11 22 33 44 55 66] print fourth 199.4.80.1 } ] free [[series] [] { ??? } ] head [[series] [head? tail tail?] { str: "all things" print head insert str "with " here: find str "all" print here print head here } ] head? [[series] [head tail tail?] { cds: [ "Rockin' REBOLs" "Carl's Addiction" "Jumpin' Jim" ] print head? cds cds: tail cds print head? cds until [ cds: back cds print first cds head? cds ] } ] index? [[series] [length? offset? head head? tail tail? pick skip] { str: "with all things considered" print index? str print index? find str "things" blk: [264 "Rebol Dr." "Calpella" CA 95418] print index? find blk 95418 } ] offset? [[series] [length? offset? head head? tail tail? pick skip] { Return the distance between two positions within a series. } ] insert [[series modify] [append change clear remove join] { If the value is a series compatible with the first (block or string-based datatype), then all of its values will be inserted. The series position just past the insert is returned, allowing multiple inserts to be cascaded together. This function includes many refinements. /PART allows you to specify how many elements you want to insert. /ONLY will force a block to be insert, rather than its individual elements. (Is only done if first argument is a block datatype.) /DUP will cause the inserted series to be repeated a given number of times. The series will be modified. str: copy "here this" insert str "now " print str insert tail str " message" print str insert tail str reduce [tab now] print str insert insert str "Tom, " "Tina, " print str insert/dup str "." 7 print str insert/part tail str next "!?$" 1 print str blk: copy ["hello"] insert blk 'print probe blk insert tail blk http://www.rebol.com probe blk insert/only blk [separate block] probe blk } ] join [[series] [rejoin form reform mold remold insert] { Creates a new value as the return. The first argument determines the datatype of the returned value. When the first argument is a type of series, the return value will be that type of series (STRING, FILE, URL, BLOCK, etc.). When the first argument is a scalar value, the return will always be a string. When the second argument is a block, it will be evaluated and all of its values joined to the return value. probe join "super" "duper" probe join %file ".txt" probe join http:// ["www.rebol.com/" %index.html] probe join "t" ["e" "s" "t"] probe join 11:11 "PM" probe join [1] ["two" 3 "four"] } ] last [[series] [first pick tail tail?] { An error will occur if no value is found. Use the PICK function to avoid this error. print last "REBOL" print last [11 22 33 44 55 66] } ] last? [[series] [] { ??? } ] length? [[series] [head] { The length is the number of values from the current position to the tail. If the current position is the head, then the length will be that of the entire series. print length? "REBOL" print length? [1 2 3 4 5] print length? [1 2 3 [4 5]] } ] parse [[series] [trim] { Parsing provides a means of recognizing a series of characters that appear in a particular order. Essentially, it is a method of finding and matching patterns. The rules argument supplies a block of grammar productions that are to be matched. There is also a simple parse mode that does not require rules, but takes a string of characters to use for splitting up the input string. Parse also works in conjunction with bitsets (charset) to specify groups of special characters. The result returned from a simple parse is a block of values. For rule-based parses, it returns TRUE if the parse succeeded through the end of the input string. The /ALL refinement indicates that all the characters within a string will be parsed. Otherwise, spaces, tabs, newlines, and other non-printable characters will be treated as spaces. The /CASE refinement specifies that a string is to be parsed case sensitive. print parse "divide on spaces" none print parse "Harry Haiku, 264 River Rd., Ukiah, 95482" "," ;page: read http://www.rebol.com ;parse page [thru <title> copy title to ] ;print title digits: charset "0123456789" area-code: ["(" 3 digits ")"] phone-num: [3 digits "-" 4 digits] print parse "(707)467-8000" [[area-code | none] phone-num] } ] pick [[series port tuple] [first second third fourth fifth find select] { The value is picked relative to the current position in the series (not necessarily the head of the series). The VALUE argument may be INTEGER or LOGIC. A positive integer positions forward, a negative positions backward. If the INTEGER is out of range, NONE is returned. If the value is LOGIC, then TRUE refers to the first position and FALSE to the second (same order as EITHER). An attempt to pick a value beyond the limits of the series will return NONE. str: "REBOL" print pick str 2 print pick 199.4.80.1 3 print pick ["this" "that"] now/time > 12:00 } ] poke [[series port tuple] [pick change] { Similar to CHANGE, but also takes an index into the series. str: "AXB" poke str 2 #"/" print str print poke 1.2.3.4 2 10 } ] rejoin [[series string] [join form reform] { Similar to JOIN but accepts only one argument, the block (which will be reduced first). No spaces are inserted between values. print rejoin ["time=" now/time] } ] remove [[series modify] [append change clear insert sort] { Normally removes just a single value from the current position. However, you can remove any number of values with the /PART refinement. str: copy "send it here" remove str print str remove/part str find str "it" print str remove/part str 3 print str blk: copy [red green blue] remove next blk probe blk } ] repend [[series] [] { ??? } ] replace [[series modify] [insert remove change] { Searches target block or series for specified data and replaces it with data from the replacement block or series. Block elements may be of any datatype. The /ALL refinement replaces all occurrences of the searched data in the target block or series. str: "a time a spec a target" replace str "a " "on " print str replace/all str "a " "on " print str fruit: ["apples" "lemons" "bananas"] replace fruit "lemons" "oranges" print fruit numbers: [1 2 3 4 5 6 7 8 9] replace numbers [4 5 6] ["four" "five" "six"] print numbers } ] reverse [[series modify] [insert replace sort] { Reverses the order of elements in a series or tuple. The /PART refinement reverses the specified number of elements from the current index forward. If the number of elements specified exceeds the number of elements left in the series or tuple, the elements from the current index to the end will be reversed. For tuple values the current index cannot be moved so the current index is always the beginning of the tuple. blk: copy [1 "two" 3 "four" 5 "six"] reverse blk print blk blk: copy [1 "two" 3 "four" 5 "six"] reverse/part next blk 4 print blk print reverse 1.2.3.4 text: "It is possible to reverse one word in a sentence." reverse/part (find text "reverse") (length? "reverse") print text print reverse/part 1.2.3.4 2 } ] second [[series] [pick first third fourth fifth] { An error will occur if no value is found. Use the PICK function to avoid this error. print second "REBOL" print second [11 22 33 44 55 66] print second 15-Jun-1999 print second 199.4.80.1 print second 12:34:56.78 } ] select [[series] [find switch] { Similar to the FINDfunction, but returns the next value in the series rather than the position of the match. Returns NONE if search failed. The /ONLY refinement is evaluated for a block argument and is ignored if the argument is a string. blk: [red 123 green 456 blue 789] print select blk 'red weather: [ "Ukiah" [clear 78 wind from NW at 5 MPH] "Santa Rosa" [overcast 65 wind from N at 10 MPH] "Eureka" [rain 62 wind from N at 15 MPH] ] probe select weather "Eureka" } ] skip [[series] [at index? next back] { For example, SKIP series 1 is the same as NEXT. If skip attempts to move beyond the head or tail it will be stopped at the head or tail. str: "REBOL" print skip str 3 blk: [11 22 33 44 55] print skip blk 3 } ] sort [[series modify] [append change clear insert remove] { If you are sorting records of a fixed size, you will need to use the /SKIP refinement to specify how many elements to ignore. Normally sorting is not sensitive to character cases, but you can make it sensitive with the /CASE refinement. A /COMPARE function can be specified to perform the comparison. This allows you to change the ordering of the SORT. Sorting will modify the series passed as the argument. blk: [799 34 12 934 -24 0] print sort blk names: ["Fred" "fred" "FRED"] print sort/case names name-ages: [ "Larry" 45 "Curly" 50 "Mo" 42 ] print sort/skip name-ages 2 names: [ "Larry" "Curly" "Mo" ] print sort/compare names func [a b] [a < b] print sort "edcba" } ] tail [[series] [tail? head head?] { Access to the tail allows insertion at the end of a series (because insertion always occurs before the specified element). blk: copy [11 22 33] insert tail blk [44 55 66] print blk } ] tail? [[series] [empty? tail head head?] { This function is the best way to detect the end of a series while moving through it. print tail? "string" print tail? tail "string" str: "Ok" print tail? tail str print tail? next next str items: [oven sink stove blender] while [not tail? items] [ print first items items: next items ] blk: [1 2] print tail? tail blk print tail? next next blk } ] third [[series] [first second fourth fifth pick] { An error will occur if no value is found. Use the PICK function to avoid this error. print third "REBOL" print third [11 22 33 44 55 66] print third 15-Jun-1999 print third 199.4.80.1 print third 12:34:56.78 } ] charset [[set] [bitset char! char?] { A shortcut for MAKE BITSET! Used commonly for character based bit sets. chars: charset "aeiou" print find chars "o" print find "there you go" chars digits: charset "0123456789" area-code: ["(" 3 digits ")"] phone-num: [3 digits "-" 4 digits] print parse "(707)467-8000" [[area-code | none] phone-num] } ] difference [[set series] [intersect union] { Returns the elements of two series that are not present in both. lunch: [ham cheese bread carrot] dinner: [ham salad carrot rice] probe difference lunch dinner print difference [1 3 2 4] [3 5 4 6] string1: "CBAD" ; A B C D scrambled string2: "EDCF" ; C D E F scrambled print difference string1 string2 } ] exclude [[set series] [] { ??? } ] extract [[set series] [] { ??? } ] intersect [[set series] [difference union] { Returns all elements within two blocks or series that exist in both. To obtain a unique set (to remove duplicate values) you can intersect a series with itself. lunch: [ham cheese bread carrot] dinner: [ham salad carrot rice] probe intersect lunch dinner print intersect [1 3 2 4] [3 5 4 6] string1: "CBAD" ; A B C D scrambled string2: "EDCF" ; C D E F scrambled print intersect string1 string2 items: [1 1 2 3 2 4 5 1 2] print intersect items items ; get unique set str: "abcacbaabcca" print intersect str str } ] union [[set series] [difference intersect] { Returns all elements present within two blocks or strings ignoring the duplicates. To obtain a unique set (to remove duplicate values) you can union a series with itself. lunch: [ham cheese bread carrot] dinner: [ham salad carrot rice] probe union lunch dinner print sort union [1 3 2 4] [3 5 4 6] string1: "CBDA" ; A B C D scrambled string2: "EDCF" ; C D E F scrambled print sort union string1 string2 items: [1 1 2 3 2 4 5 1 2] print union items items ; get unique set str: "abcacbaabcca" print union str str } ] unique [[set series] [] { ??? } ] build-tag [[string] [tag! to-tag compose] { Constructs an HTML or XML tag from a block. Words within the block are used to construct the attribute words within the tag. If they are followed by a value, that value will be assigned to the attribute. Parenthesized elements are evaluated as expressions and their resulting value is used. print build-tag [font size 3] print build-tag [font size (10 / 2)] print build-tag [img src %image.jpg] site: http://www.rebol.com/ main-index: %index.html print build-tag [A HREF (join site main-index)] root: %images/ download: %download1.gif alt-download: "Download the Latest REBOL!" print build-tag [IMG SRC (rejoin [site root download]) ALT (alt-download)] } ] checksum [[string] [string! string? any-string! any-string?] { Generally, a checksum is a number which accompanies data to verify that the data has not changed (did not have errors). The /TCP refinement is used to compute the standard TCP networking checksum. print checksum "now is the dawning" print checksum "how is the dawning" print checksum/tcp "now is the dawning" print checksum/tcp "how is the dawning" } ] compress [[string] [decompress] { As with all compressed files, keep an uncompressed copy of the original data file as a backup. print compress "now is the dawning" string: form first system/words print length? string small: compress string print length? small } ] debase [[string] [enbase dehex] { Converts from an encoded string to the binary value. Primarily used for BASE-64 decoding. The /BASE refinement allows selection of number base as 64, 16, 2. Default is base64. probe debase "MTIzNA==" probe debase/base "12AB C456" 16 enbased: probe enbase "a string of text" probe string? enbased ; enbased value is a string debased: probe debase enbased ; converts to binary value probe to-string debased ; converts back to original string } ] decode-cgi [[string] [] { Constructs a block of word value pairs from a name=value text string argument delineated with the "&" character. Obtain CGI queries by using DECODE-CGI to evaluate system/options/cgi/query-string, where CGI query strings are stored for reference. ex-query-string: "fname=John&lname=Doe&email=who@where.dom" cgi-input: make object! decode-cgi ex-query-string print probe cgi-input print ["Name: " cgi-input/fname cgi-input/lname] print ["Email: " cgi-input/email] } ] decompress [[string] [compress enbase debase] { If the data passed to the DECOMPRESS function has been altered or corrupted, a decompression error will occur. write %file.txt read http://www.rebol.com/ probe size? %file.txt save %file.comp compress read %file.txt probe size? %file.comp write %file.decomp decompress load %file.comp probe size? %file.decomp } ] dehex [[string] [to-hex debase enbase] { Converts the standard URL hex sequence that begins with a % followed by a valid hex value. Otherwise, the sequence is not converted and will appear as written. print dehex "www.com/a%20dir/file" print dehex "ABCD%45" } ] detab [[string] [entab] { The REBOL language default tab size is four spaces. Use the /SIZE refinement for other sizes such as eight. DETAB will remove tabs from the entire string even beyond the first non-space character. The series passed to this function is modified as a result. text: " lots of tabs here" print detab copy text print detab/size text 8 } ] enbase [[string] [debase dehex] { Converts from a string or binary into an encode string value. Primarily used for BASE-64 encoding. The /BASE refinement allows selection of base as 64, 16, 2. Default is base64. print enbase "Here is a string." print enbase/base #{12abcd45} 16 } ] entab [[string] [detab] { The REBOL language default tab-size is four spaces. Use the /SIZE refinement for other sizes such as eight. ENTAB will only place tabs at the beginning of the line (prior to the first non-space character). The series passed to this function is modified as a result. text: { no tabs in this sentence } remove head remove back tail text probe text probe entab copy text print entab copy text probe entab/size copy text 2 print entab/size copy text 2 } ] form [[string] [mold reform remold join] { FORM creates the user-friendly format of the value, its standard PRINT format, not its molded (or source) format. When given a block of values, spaces are inserted between each values (except after a newline). To avoid the spaces between values use INSERT or JOIN. Note that FORM does not evaluate the values within a block. To do so, either use REFORM or perform a REDUCE prior to the FORM. print form 10:30 print form %image.jpg print form [123 "-string-" now] print reform [123 "-string-" now] } ] import-email [[string] [] { Constructs an easily referenced object from an email message inherited by system/standard/email. The object's elements are defined by the email's header field names and are assigned the value of the corresponding fields. message: trim { To: John Doe From: Jane Doe Subject: Check Out REBOL! John, I found this great new scripting language that will be easier to use and more productive. Check out www.rebol.com! ---Jane } email: import-email message print email/from print email/to print email/content } ] lowercase [[string] [uppercase] { The series passed to this function is modified as a result. print lowercase "ABCDEF" print lowercase/part "ABCDEF" 3 } ] mold [[string] [form remold join insert reduce] { MOLD differs from FORM in that MOLD produces a REBOL readable string. For example, a block will contain brackets [ ] and strings will be " " quoted or use braces { } (if it is long or contains special characters). When given a block of values, spaces are inserted between each values (except after a newline). To avoid the spaces between values use INSERT to insert the block into a string. MOLD does not evaluate the values within a block. To do so use REMOLD. print mold 10:30 print mold %image.jpg print mold [1 2 3] } ] parse-email-addrs [[string] [] { ??? } ] parse-header [[string] [] { ??? } ] parse-header-date [[string] [] { ??? } ] parse-xml [[string] [] { ??? } ] reform [[string] [form mold remold join rejoin] { Identical to FORM but reduces its argument first. Spaces are inserted between each value. probe reform ["the time is:" now/time] probe form ["the time is:" now/time] } ] remold [[string] [mold reduce] { Identical to MOLD, but reduces its argument first. Spaces are inserted between each values in a block. print remold ["the time is:" now/time] } ] trim [[string] [parse] { Generally, TRIM is for removing spaces from the head and tail of a string. However, there are several other useful modes of operation. One of the most useful is /AUTO which will do a "smart" trim of the indentation of text lines. You can restrict the trim to the /HEAD or the /TAIL. Or, you can also remove /ALL space. If you TRIM/LINES then all line breaks will be replaced with spaces. This is useful for word wrapping and web page kinds of applications. The string provided for the argument will be modified by this function str: " string " print trim str str: { Now is the winter of our discontent made glorious summer by this sun of York. } print trim/auto copy str } ] trim-last [[string] [] { ??? } ] uppercase [[string modify] [lowercase] { The series passed to this function is modified as a result. print uppercase "abcdef" print uppercase/part "abcdef" 1 } ] browse [[system] [] { If the browser cannot be found, nothing will happen. } ] now [[system] [date?] { For accuracy, first verify that the time, date and timezone are correctly set on the computer. print now print now/date print now/time print now/zone print now/weekday } ] protect [[system word] [unprotect] { Prevents a word from being modified using a set operation. An attempt to modify a locked word generates an error. test: "This word is protected!" protect 'test if error? try [test: "Trying to change test..."] [ print "Couldn't change test!" ] print test unprotect 'test } ] protect-system [[system] [] { ??? } ] recycle [[system] [] { Useful for forcing a garbage collection. You can also turn automatic memory management on and off. Default is RECYCLE/ON. recycle recycle/off recycle/on } ] unprotect [[system word] [protect] { Unlocks a word locked with PROTECT so its value may be modified. test: "I'm protected, no-one may change me!" protect 'test if error? try [test: "Trying to change test..."] [ print "Couldn't change test!" ] print test unprotect 'test if error? try [test: "Trying to change test..."] [ print "Couldn't change test!" ] } ] upgrade [[system] [about license] { Checks your version of REBOL against the latest released version (requires a network connection) and prompts you to download the latest version if your current version is outdated. If your current version of REBOL is up to date, this is indicated. ;upgrade } ] any-block! [[type] [block! paren! path! any-block? any-function! any-string! any-type!] { Represents any type of block. When provided within the function's argument specification, it requests the interpreter verify that the argument value is of the specified type when the function is evaluated. fun: func [arg [any-block!]] [probe :arg] fun [1 2 3] fun first [(1 2 3)] fun 'a/b/c } ] any-block? [[type] [block? paren? path? any-function? any-string? any-type? any-word?] { Returns FALSE for all other values. print any-block? [1 2] print any-block? first [(1 2) 3] print any-block? 'a/b/c print any-block? 12 } ] any-function! [[type] [function! native! op! any-block! any-string! any-type! any-word!] { Represents functions of any type. When provided within the function's argument specification, it requests the interpreter verify that the argument value is of the specified type when the function is evaluated. fun: func [arg [any-function!]] [print type? :arg] fun :print fun :fun fun :+ } ] any-function? [[type] [function? native? op? any-block? any-string? any-type? any-word?] { Returns FALSE for all other values. print any-function? :find print any-function? :+ print any-function? func [] [print "hi"] print any-function? 123 } ] any-string! [[type] [string! file! email! url! any-block! any-function! any-type!] { Represents any type of string. When provided within the function's argument specification, it requests the interpreter verify that the argument value is of the specified type when the function is evaluated. fun: func [arg [any-string!]] [print arg] fun "string" fun %file.txt fun http://www.rebol.com fun email@rebol.com } ] any-string? [[type] [string? file? email? url? any-block? any-function? any-type?] { Returns FALSE for all other values. if any-string? "Hello" [print "a string"] probe any-string? email@rebol.com probe any-string? ftp://ftp.rebol.com probe any-string? %/path/to/file.txt probe any-string? 11-Jan-2000 } ] any-type! [[type] [any-block! any-function! any-string! any-word!] { Represents any type of value. When provided within the function's argument specification, that argument becomes optional to the function. Optional arguments must be the last specified within a function's argument specification. fun: func [arg [any-type!]] [ print either value? 'arg [arg]["no argument specified"] ] fun 123 fun "test" fun [1 3 4] fun } ] any-type? [[type] [any-type! any-block? any-function? any-string? any-word?] { Returns TRUE for values of any type. Because any value that can successfully be passed to ANY-TYPE? is a value of some type, ANY-TYPE? never returns FALSE. However, an error will occur if a value cannot be passed to ANY-TYPE?. print any-type? http://www.REBOL.com } ] any-word! [[type] [any-word? any-block! any-function! any-string! any-type!] { Represents any type of word. When provided within the function's argument specification, it requests the interpreter verify that the argument value is of the specified type when the function is evaluated. fun: func [word [any-word!]] [probe type? :word] foreach w [word set-word: 'lit-word :get-word][fun :w] } ] any-word? [[type] [any-word! any-block? any-function? any-string? any-type?] { Returns FALSE for all other values. print any-word? 'word foreach word [word set-word: 'lit-word :get-word 123] [ print [ rejoin [{"} mold :word {"}] either any-word? :word [ "is a type of word."]["is not a type of word."] ] ] } ] binary! [[type] [binary? make type?] { The binary datatype is a series of 8 bit bytes. The word BINARY! represents the BINARY datatype both externally to the user and internally within the system. When supplied as an argument to the MAKE function, it specifies the type of value to be created. When provided within the function's argument specification, it requests the interpreter to verify that the argument value is of the specified type when the function is evaluated. probe make binary! "1234" } ] binary? [[type] [binary! type?] { Returns FALSE for all other values. print binary? #{13FF Acd0} print binary? 1234 } ] bitset! [[type] [bitset? charset] { The bitset datatype is a set of bits to represent existence of characters or small integer numbers. The bitset! word represents the BITSET datatype, both externally to the user and internally within the system. When supplied as an argument to the MAKE function, it specifies the type of value to be created. When provided within the function's argument specification, it requests the interpreter to verify that the argument value is of the specified type when the function is evaluated. test-bits: make bitset! "12345" if find test-bits "2" [print "Found it!"] print find test-bits "236" print find test-bits "129" test-bits: make bitset! 96 insert test-bits 40 print find test-bits 40 print find test-bits 37 } ] bitset? [[type] [bitset!] { Returns FALSE for all other values. print bitset? make bitset! "abc" print bitset? 123 } ] block! [[type] [block? make type?] { Represents the BLOCK datatype, both externally to the user and internally within the system. When supplied as an argument to the MAKE function, it specifies the type of value to be created. When provided within a function's argument specification, it requests the interpreter to verify that the argument value is of that type when the function is evaluated. block: make block! 100 repeat n 10 [insert block random n * 10] print block fun: func [arg [block!]] [print arg] fun [1 2 3] } ] block? [[type] [block! type?] { Returns FALSE for all other values. print block? [1 2 3] print block? "1 2 3" data: load "1 2 3" ; LOAD converts "1 2 3" into a block if block? data [print data] } ] char! [[type] [char? make type?] { Represents the CHAR datatype, both externally to the user and internally within the system. When supplied as an argument to the MAKE function, it specifies the type of value to be created. When provided within the specification of the argument of a function, it requests the interpreter to check that the argument value is of the specified type when the function is evaluated. char: #"A" print type? char print char print head insert "BCD" char } ] char? [[type] [char! type?] { Returns FALSE for all other values. print char? #"1" print char? 1 } ] datatype! [[type] [datatype? make] { Represents the DATATYPE datatype, both externally to the user and internally within the system. Any datatype identifier such as STRING!, NUMBER! or SERIES! are of the DATATYPE datatype, including DATATYPE! itself. When provided within the function's argument specification, it requests the interpreter to verify the argument value is of the datatype DATATYPE when the function is evaluated. make-121: func [arg [datatype!]][make arg 121] probe make-121 string! ; allocates memory for a string probe make-121 block! ; allocates memory for a block probe make-121 integer! ; makes an integer "121" probe make-121 time! ; makes a time value (121 seconds) } ] datatype? [[type] [datatype!] { Returns FALSE for all other values. print datatype? integer! print datatype? 1234 } ] date! [[type] [date? make type? time!] { Represents the DATE datatype, both externally to the user and internally within the system. Date value elements may be delineated either by "/" or "-" characters dd/mm/yyyy, or dd-mm-yyyy. Several date formats are recognized by the language. These formats are dd/mm/yy, dd/mm/yyyy, yyyy/mm/dd; The 'mm' may be represented as a numeric month (1-12), a month name or the abbreviated month name. Regardless how the date is entered, date values are returned by REBOL in the dd-mmm-yyyy format with 'mmm' representing the abbreviated month. For instance, the third of March in the year 2001 is represented as 3-Mar-2001. When supplied as an argument to the MAKE function, it specifies the type of value to be created. When provided within the specification of the argument of a function, it requests the interpreter to check that the argument value is of the specified type when the function is evaluated. The components of a date value may be accessed using refinements supported by the DATE datatype. These refinements are /DAY (get the day), /MONTH (get the month), /YEAR (get the year), /WEEKDAY (get the weekday [1-7/Mon-Sun]), /JULIAN (get the day of the year), /ZONE (get the time zone if present), /DATE (extract the day month and year from a date containing the time) and /TIME (get the time if present). Further refinements may be used with the /TIME refinement to obtain the components a time value pulled from a date. These refinements are /HOUR (get the hour), /MINUTE (get the minute), and /SECOND (get the second). when: make date! [30 6 2001] probe when probe when/day probe when/month probe when/year probe pick [Mon Tue Wed Thu Fri Sat Sun] when/weekday probe when/julian when: 12-Jan-2001/18:06:01-8:00 probe when/time probe when/time/hour probe when/time/minute probe when/time/second probe when/zone probe when/date fun: func [arg [date!]][ days: [Monday Tuesday Wednesday Thursday Friday Saturday Sunday] weekday: pick days arg/weekday print [arg/date "is on a" form weekday] ] fun 3/3/2001 fun when fun now } ] date? [[type] [date! type?] { Returns FALSE for all other values. print date? 1/3/69 print date? 12:39 } ] decimal! [[type] [decimal? number! make type?] { Represents the DECIMAL datatype, both externally to the user and internally within the system. When supplied as an argument to the MAKE function, it specifies the type of value to be created. When provided within the function's argument specification, it requests the interpreter to verify that the argument value is of the specified type when the function is evaluated. value: make decimal! "3.1415" print value print make decimal! [32 3] print make decimal! [3.2 45] } ] decimal? [[type] [decimal! number? type?] { Returns FALSE for all other values. print decimal? 1.2 print decimal? 1 } ] email! [[type] [email? make type?] { Represents the EMAIL datatype, both externally to the user and internally within the system. When supplied as an argument to the MAKE function, it specifies the type of value to be created. When provided within the function's argument specification, it requests the interpreter to verify that the argument value is of that type when the function is evaluated. mail: make email! ["user" "domain.com"] print mail print mail/user print mail/host } ] email? [[type] [email! type?] { Returns FALSE for all other values. print email? info@rebol.com print email? http://www.REBOL.com } ] error! [[type] [error?] { Represents the ERROR datatype, both externally to the user and internally within the system. When supplied as an argument to the MAKE function, it specifies the type of value to be created. When provided within the function's argument specification, it requests the interpreter to verify that the argument value is of the specified type when the function is evaluated. (Example commented out so that this script doesn't stop when error is thrown.) ;throw make error! "User Error!" } ] error? [[type] [error!] { Returns FALSE for all other values. This is useful for determining if a TRY function returned an error. if error? try [1 + "x"][ print "Did not work." ] } ] event? [[type] [] { ??? } ] file! [[type] [file? make type?] { Represents the FILE datatype, both externally to the user and internally within the system. A file is directly represented in REBOL as a percent symbol (%), followed by a file name, or path. When supplied as an argument to the MAKE function, it specifies the type of value to be created. When provided within the function's argument specification, it requests the interpreter to verify that the argument value is of that type when the function is evaluated. probe make file! "image.jpg" write %rebol-test-file.r "some file data" show-contents: func [file [file!]] [ if exists? file [print read file] ] show-contents %rebol-test-file.r } ] file? [[type] [file! type?] { Returns FALSE for all other values. Note that FILE? does not check for the existence of a file, but whether or not a value is the FILE! datatype. print file? %file.txt print file? "REBOL" } ] function! [[type] [function? make type?] { Represents the FUNCTION datatype, both externally to the user and internally within the system. When supplied as an argument to the MAKE function, it specifies the type of value to be created. When provided within the function's argument specification, it requests the interpreter to verify that the argument value is of the specified type when the function is evaluated. Setting a function to a word is optional. The REBOL language also allows unnamed functions. test: make function! [str] [print str] test "simple" funct: make function! [args body][make function! args body] print do (make function! [n] [n * 123]) 10 } ] function? [[type] [any-function? function! type?] { Returns FALSE for all other values. print function? :func print function? "test" } ] get-word! [[type] [get-word? word! set-word! lit-word!] { Represents the GET-WORD datatype, both externally to the user and internally within the system. When supplied as an argument to the MAKE function, it specifies the type of value to be created. When provided within the function's argument specification, it requests the interpreter to verify that the argument value is of the specified type when the function is evaluated. probe make get-word! "test" } ] get-word? [[type] [get-word! word? set-word? lit-word?] { Returns FALSE for all other values. print get-word? second [pr: :print] } ] hash! [[type] [hash? block! list!] { Represents the HASH datatype, both externally to the user and internally within the system. When supplied as an argument to the MAKE function, it specifies the type of value to be created. When provided within the specification of the argument of a function, it requests the interpreter to check that the argument value is of the specified type when the function is evaluated. FIND performs faster with HASH! than with a BLOCK!. blk: ["Doug" "Mary" "Kas" "Jodi" "Patrick" "Polly" "Eli"] hash: make hash! blk find hash "Polly" } ] hash? [[type] [hash! block? list?] { Returns FALSE for all other values. test-hash: make hash! [1 2 3 4] if hash? test-hash [print "It's a hash."] } ] image? [[type] [] { ??? } ] integer! [[type] [integer? make type?] { Represents the INTEGER datatype, both externally to the user and internally within the system. When supplied as an argument to the MAKE function, it specifies the type of value to be created. When provided within the function's argument specification, it requests the interpreter to verify that the argument value is of the specified type when the function is evaluated. print make integer! "12345" print make integer! 123.45 } ] integer? [[type] [integer! type?] { Returns FALSE for all other values. print integer? -1234 print integer? "string" } ] issue! [[type] [issue? make type?] { Represents the ISSUE datatype, both externally to the user and internally within the system. When supplied as an argument to the MAKE function, it specifies the type of value to be created. When provided within the function's argument specification, it requests the interpreter to verify that the argument value is of the specified type when the function is evaluated. print make issue! "1234-56-7890" } ] issue? [[type] [issue! type?] { Returns FALSE for all other values. print issue? #1234-5678-9012 print issue? #467-8000 print issue? $12.56 } ] library? [[type] [] { ??? } ] list! [[type] [list?] { Represents the LIST datatype, both externally to the user and internally within the system. When supplied as an argument to the MAKE function, it specifies the type of value to be created. When provided within the function's argument specification, it requests the interpreter to verify that the argument value is of the specified type when the function is evaluated. APPEND, INSERT, and REMOVE perform faster with LIST! than with BLOCK!. blk: ["Carla" "Brian" "Karen" "Adam" "Jeremy"] list: make list! blk probe list remove list probe list append list "Susan" probe list } ] list? [[type] [list!] { Returns FALSE for all other values. test-list: make list! [1 2 3 4] if list? test-list [print "It's a list."] } ] lit-path! [[type] [path! set-path! path?] { Represents the LIT-PATH datatype, both externally to the user and internally within the system. When supplied as an argument to the MAKE function, it specifies the type of value to be created. When provided within the function's argument specification, it requests the interpreter to verify that the argument value is of the specified type when the function is evaluated. probe make lit-path! [a b c] } ] lit-path? [[type] [] { ??? } ] lit-word! [[type] [word! set-word! get-word!] { Represents the LIT-WORD datatype, both externally to the user and internally within the system. When supplied as an argument to the MAKE function, it specifies the type of value to be created. When provided within the function's argument specification, it requests the interpreter to verify that the argument value is of the specified type when the function is evaluated. probe make lit-word! "test" } ] lit-word? [[type] [word! set-word? get-word!] { Returns FALSE for all other values. probe lit-word? first ['foo bar] } ] logic! [[type] [logic? make type?] { Represents the LOGIC datatype, both externally to the user and internally within the system. When supplied as an argument to the MAKE function, it specifies the type of value to be created. When provided within the function's argument specification, it requests the interpreter to verify that the argument value is of the specified type when the function is evaluated. print make logic! 1 print make logic! 0 } ] logic? [[type] [logic! type?] { Returns FALSE for all other values. Note that all conditional functions will accept more than just a LOGIC value. A NONE will act as FALSE, and all other values other than logic will act as TRUE. print logic? true print logic? 123 } ] make [[type] [copy type?] { The TYPE argument indicates the datatype to create. The form of the constructor is determined by the datatype. For most series datatypes, a number indicates the size of the initial allocation. str: make string! 1000 blk: make block! 10 cash: make money! 1234.56 print cash time: make time! [10 30 40] print time } ] money! [[type] [money? make type?] { Represents the MONEY datatype, both externally to the user and internally within the system. When supplied as an argument to the MAKE function, it specifies the type of value to be created. When provided within the function's argument specification, it requests the interpreter to verify that the argument value is of the specified type when the function is evaluated. print make money! "123" print make money! [EUR 123.45] } ] money? [[type] [money! type?] { Returns FALSE for all other values. print money? $123 print money? EUR$123 print money? 123.45 } ] native! [[type] [native? make type?] { Represents the NATIVE datatype, both externally to the user and internally within the system. When supplied as an argument to the MAKE function, it specifies the type of value to be created. When provided within the function's argument specification, it requests the interpreter to verify that the argument value is of the specified type when the function is evaluated. } ] native? [[type] [native! type?] { Returns FALSE for all other values. When passing a function to NATIVE? to be checked, it must be denoted with ":". This is because the ":word" notation passes a word's reference, not the word's value. NATIVE? can only determine whether or not a function is a native if it is passed the function's reference. probe native? :native? ; it's actually an ACTION! probe native? "Vichy" probe native? :if } ] none! [[type] [none none?] { Represents the NONE datatype, both externally to the user and internally within the system. When supplied as an argument to the MAKE function, it specifies the type of value to be created. When provided within the function's argument specification, it requests the interpreter to verify that the argument value is of the specified type when the function is evaluated. } ] none? [[type] [none none!] { Returns FALSE for all other values. print none? NONE print none? pick "abc" 4 print none? find "abc" "d" } ] number! [[type] [integer! decimal!] { Represents both integer and decimal types. When provided within the function's argument specification, it requests the interpreter to verify that the argument value is of the specified type when the function is evaluated. times: func [a [number!] b [number!]] [a * b] print times 10 1.5 print times 3.1 5 } ] number? [[type] [integer? decimal?] { Returns FALSE for all other values. print number? 1234 print number? 12.34 print number? "1234" } ] object! [[type] [make object? type?] { Represents the OBJECT datatype, both externally to the user and internally within the system. When supplied as an argument to the MAKE function, it specifies the type of value to be created. When provided within the function's argument specification, it requests the interpreter to verify that the argument value is of the specified type when the function is evaluated. test: make object! [ name: "alpha" size: 12 type: 'rebol doit: func [arg][size * arg] ] print test/name print test/doit 10 } ] object? [[type] [object! type?] { Returns FALSE for all other values. print object? system } ] op! [[type] [op?] { Represents the OP datatype, both externally to the user and internally within the system. When supplied as an argument to the MAKE function, it specifies the type of value to be created. When provided within the specification of the argument of a function, it requests the interpreter to check that the argument value is of the specified type when the function is evaluated. } ] op? [[type] [op!] { Returns FALSE for all other values. print op? :and print op? :+ } ] pair? [[type] [] { ??? } ] paren! [[type] [paren? make type?] { Represents the PAREN datatype, both externally to the user and internally within the system. When supplied as an argument to the MAKE function, it specifies the type of value to be created. When provided within the specification of the argument of a function, it requests the interpreter to check that the argument value is of the specified type when the function is evaluated. print mold make paren! [1 + 2] } ] paren? [[type] [paren! type?] { Returns FALSE for all other values. A paren is identical to a block, but is immediately evaluated when found. print paren? second [123 (456 + 7)] print paren? [1 2 3] } ] path! [[type] [path? lit-path? lit-path! set-path? set-path! get-path? get-path! make refinement? refinement!] { Represents the PATH datatype, both externally to the user and internally within the system. When supplied as an argument to the MAKE function, it specifies the type of value to be created. When provided within the function's argument specification, it requests the interpreter to verify that the argument value is of the specified type when the function is evaluated. the-time: make path! [now time] probe :the-time probe the-time } ] path? [[type] [path! make] { Returns FALSE for all other values. print path? first [random/seed 10] } ] port! [[type] [port? make type?] { Represents the PORT datatype, both externally to the user and internally within the system. When supplied as an argument to the MAKE function, it specifies the type of value to be created. When provided within the function's argument specification, it requests the interpreter to verify that the argument value is of the specified type when the function is evaluated. } ] port? [[type] [port! make! type?] { Returns FALSE for all other values. file: open %newfile.txt print port? file close file print port? "test" } ] refinement! [[type] [refinement?] { Represents the REFINEMENT datatype, both externally to the user and internally within the system. When supplied as an argument to the MAKE function, it specifies the type of value to be created. When provided within the function's argument specification, it requests the interpreter to verify that the argument value is of the specified type when the function is evaluated. } ] refinement? [[type] [refinement!] { Returns FALSE for all other values. print refinement? /any print refinement? 'any } ] routine? [[type] [] { ??? } ] series! [[type] [series?] { Represents the SERIES datatype, both externally to the user and internally within the system. When supplied as an argument to the MAKE function, it specifies the type of value to be created. When provided within the function's argument specification, it requests the interpreter to verify that the argument value is of the specified type when the function is evaluated. test-series: func [list [series!]][print length? list] test-series "short string" test-series [short block] } ] series? [[type] [type? string? email? file? url? issue? tuple? block? paren?] { Returns FALSE for all other values. print series? "string" print series? [1 2 3] print series? 1234 } ] set-path! [[type] [path? make type?] { Represents the SET-PATH datatype, both externally to the user and internally within the system. When supplied as an argument to the MAKE function, it specifies the type of value to be created. When provided within the function's argument specification, it requests the interpreter to verify that the argument value is of the specified type when the function is evaluated. probe make set-path! [object field] } ] set-path? [[type] [path! make] { Returns FALSE for all other values. if set-path? first [a/b/c: 10] [print "Path found"] } ] set-word! [[type] [set-word?] { Represents the SET-WORD datatype, both externally to the user and internally within the system. When supplied as an argument to the MAKE function, it specifies the type of value to be created. When provided within the function's argument specification, it requests the interpreter to verify that the argument value is of the specified type when the function is evaluated. probe make set-word! "test" } ] set-word? [[type] [set-word!] { Returns FALSE for all other values. if set-word? first [word: 10] [print "it will be set"] } ] string! [[type] [string? make type?] { Represents the STRING datatype, both externally to the user and internally within the system. When supplied as an argument to the MAKE function, it specifies the type of value to be created. When provided within the function's argument specification, it requests the interpreter to verify that the argument value is of the specified type when the function is evaluated. str: make string! 20 insert str "hello" print str } ] string? [[type] [string! type?] { Returns FALSE for all other values. print string? "with all things considered" print string? 123 } ] struct? [[type] [] { ??? } ] tag! [[type] [tag?] { Represents the TAG datatype, both externally to the user and internally within the system. When supplied as an argument to the MAKE function, it specifies the type of value to be created. When provided within the function's argument specification, it requests the interpreter to verify that the argument value is of the specified type when the function is evaluated. print make tag! "body" print make tag! "/body" } ] tag? [[type] [tag!] { Returns FALSE for all other values. print tag? print tag? "title" } ] time! [[type] [time? make type?] { Represents the TIME datatype, both externally to the user and internally within the system. When supplied as an argument to the MAKE function, it specifies the type of value to be created. When provided within the function's argument specification, it requests the interpreter to verify that the argument value is of the specified type when the function is evaluated. time: make time! [5 30 15] ;hour min sec print time } ] time? [[type] [time! type?] { Returns FALSE for all other values. print time? 12:00 print time? 123 } ] to [[type] [] { ??? } ] to-binary [[type] [binary!] { Converts other values to BINARY. probe to-binary "123456" } ] to-bitset [[type] [bitset!] { Converts other values to BITSET. probe to-bitset [#"a" - #"z" #"A" - #"Z"] } ] to-block [[type] [block!] { Converts other values to BLOCK. print to-block "123 10:30" } ] to-char [[type] [char!] { Converts other values to CHAR. print to-char "a" print to-char 65 } ] to-date [[type] [date!] { Converts other values to DATE. print to-date "12-April-1999" } ] to-decimal [[type] [decimal!] { Converts other values to DECIMAL. print to-decimal 12.3 } ] to-email [[type] [email!] { Converts other values to EMAIL. print to-email [luke rebol.com] } ] to-event [[type] [] { ??? } ] to-file [[type] [file!] { Converts other values to FILE. print to-file ask "What file would you like to create? " } ] to-get-word [[type] [get-word!] { Converts other values to GET-WORD. probe to-get-word "test" } ] to-hash [[type] [hash!] { Converts other values to HASH. test-hash: to-hash [Bob Tina Fred Sandra Linda] print find test-hash 'Fred } ] to-hex [[type] [binary!] " print to-hex 123^/^/" ] to-idate [[type] [date! date?] { Internet date format is day, date, month, year, time (24-hour clock), timezone offset from GMT. print to-idate now } ] to-image [[type] [] { ??? } ] to-integer [[type] [integer!] { Converts other values to INTEGER. print to-integer "123" print to-integer 123.9 print to-integer #"A" } ] to-issue [[type] [issue!] { Converts other values to ISSUE. print to-issue "1234-56-7890" } ] to-list [[type] [list!] { Converts other values to LIST. test-list: to-list [Bob Tina Fred Sandra Linda] insert next test-list "Alice" print test-list } ] to-lit-path [[type] [] { ??? } ] to-lit-word [[type] [lit-word!] { Converts other values to LIT-WORD. probe to-lit-word "test" } ] to-logic [[type] [logic!] { Converts other values to LOGIC. print to-logic 1 print to-logic 0 } ] to-money [[type] [money!] { Converts other values to MONEY. print to-money 123.4 print to-money [AUS 123.4] } ] to-none [[type] [none!] { Converts other values to NONE. } ] to-pair [[type] [] { ??? } ] to-paren [[type] [paren!] { Converts other values to PAREN. print to-paren "123 456" } ] to-path [[type] [path!] { Converts other values to PATH. colors: make object! [reds: ["maroon" "brick" "sunset"]] p-reds: to-path [colors reds] print form :p-reds print p-reds insert tail p-reds "bright" print colors/reds print p-reds } ] to-refinement [[type] [refinement!] { Converts other values to REFINEMENT. } ] to-set-path [[type] [set-path!] { Converts other values to SET-PATH. colors: make object! [blues: ["sky" "sea" "midnight"]] ps-blues: to-set-path [colors blues] print form :ps-blues print ps-blues ps-blues compose [(ps-blues) "light"] print colors/blues print ps-blues } ] to-set-word [[type] [set-word!] { Converts other values to SET-WORD. probe to-set-word "test" } ] to-string [[type] [string!] { Converts other values to STRING. print to-string [123 456] } ] to-tag [[type] [tag!] { Converts other values to TAG. print to-tag ";comment:" } ] to-time [[type] [time!] { Converts other values to TIME. print to-time 75 } ] to-tuple [[type] [tuple!] { Converts other values to TUPLE. print to-tuple [12 34 56] } ] to-url [[type] [url!] { Converts other values to URL. print to-url "info@rebol.com" } ] to-word [[type] [word!] { Converts other values to WORD. print to-word "test" } ] tuple! [[type] [tuple? make type?] { Represents the TUPLE datatype, both externally to the user and internally within the system. When supplied as an argument to the MAKE function, it specifies the type of value to be created. When provided within the function's argument specification, it requests the interpreter to verify that the argument value is of the specified type when the function is evaluated. print make tuple! [10 30 40 50] } ] tuple? [[type] [tuple! type?] { Returns FALSE for all other values. print tuple? 1.2.3.4 version: 0.1.0 if tuple? version [print version] } ] type? [[type] [ make none? logic? integer? decimal? money? tuple? time? date? character? string? email? file? url? issue? word? block? paren? path? native? function? object? port? ] { To check for a single datatype, use its datatype test function (e.g. string?, time?) The /WORD refinement returns the type as a word so you can use if for FIND, SELECT, SWITCH, and other functions. print type? 10 print type? :type? value: 10:30 print switch type?/word value [ integer! [value + 10] decimal! [to-integer value] time! [value/hour] date! [first value/time] ] } ] unset? [[type] [value? unset!] { Returns TRUE if a value is UNSET. Normally you should use VALUE? to test if a word has a value. if unset? do [print "test"] [print "Nothing was returned"] } ] url! [[type] [url? make type?] { Represents the URL datatype, both externally to the user and internally within the system. When supplied as an argument to the MAKE function, it specifies the type of value to be created. When provided within the function's argument specification, it requests the interpreter to verify that the argument value is of the specified type when the function is evaluated. print make url! "http://www.REBOL.com" } ] url? [[type] [url! type?] { Returns FALSE for all other values. print url? http://www.REBOL.com print url? "test" } ] word! [[type] [make type? word?] { Represents the WORD datatype, both externally to the user and internally within the system. When supplied as an argument to the MAKE function, it specifies the type of value to be created. When provided within the function's argument specification, it requests the interpreter to verify that the argument value is of the specified type when the function is evaluated. print make word! "test" } ] word? [[type] [word! type?] { Returns FALSE for all other values. To test for "word:", ":word", or "'word", use the SET?, GET?, and LITERAL? functions. print word? second [1 two "3"] } ] ;--VIEW------------------------------ caret-to-offset [[view] [] { This function is provided to convert from a string character index position to an X-Y offset within the text of a face. This is used primarily for text editing or for text mapping operations such as for creating colored or hyperlinked text. out: layout [ bx: box 10x15 red tx: body 100x100 ] tx/text: {This is an example character string.} xy: caret-to-offset tx at tx/text 14 bx/offset: tx/offset + xy view out Note that the resulting offset (xy) was added to the face position (tx/offset) to find the correct position to locate the box (bx). In the above example the caret-to-offset function was used on a face that have not yet been shown, but it can also be used after a face has been shown. Remember that when making changes to the contents of strings that are longer than 200 characters, you must set the text face line-list to NONE to force the recomputation of all line breaks. See the offset-to-caret function for the reverse conversion. This function can also work on faces that have never been shown. This makes pre-display processing, colored text, and hyperlinking possible using this function in combination with SIZE-TEXT. } ] center-face [[view] [] { This function is used for centering a face relative to the screen or relative to other faces. It is useful for displaying dialog boxes or other types of windows that require the user's attention. In the example below, a layout face is shown in its default position, then it is displayed in the center of the screen. out1: layout [ vh2 "Bust'n Chops" body "With the Internet we're bust'n chops worldwide." ] view out1 center-face out1 view out1 To position a face relative to another face use the /with refinement. out2: layout [vh2 "Ok boss."] out1/offset: 200x200 center-face/with out2 out1 view/new out1 view/new out2 wait 2 unview/all The out2 face is centered over the out1 face. } ] choose [[view] [] { This function pops-up a list of choices for user selection. The function does not return until the user has picked one of the choices or clicked outside of the popup area. The CHOOSE function takes a block of choices as its first argument. Its second argument is a function that is called when a choice has been made. choose ["A" "B" "C"] func [face btn] [print face/text] } ] clear-fields [[view] [] { Clear all the fields of a layout. This is often used for input forms each time they are displayed. } ] confine [[view] [] { ??? } ] do-events [[view control] [] { Process user events. When this function is called the program becomes event driven. This function does not return until all windows have been closed. } ] find-window [[view] [] { ??? } ] focus [[view] [unfocus] { Specify that the face is to receive keyboard input. Normally used with the FIELD and AREA styles. Only one face can have the focus at a time. The focus can be changed at an time by calling the FOCUS function with a new face. To remove the focus, call the UNFOCUS function. out: layout [ h2 "Focus example:" f1: field "field 1" f2: field "field 2" button "Focus 2" [focus f2] button "Focus 1" [focus f1] button "Unfocus" [unfocus] button "Close" [unview] ] focus f1 view out Focus is set automatically when a user clicks on a text face. } ] get-style [[view] [] { ??? } ] hide [[view] [] { HIDE has the opposite effect of SHOW. It temporarily removes the face from view, but does not remove the face from its parent face's pane. The face will become visible again the next time the face is shown either directly or indirectly through one of its parent faces. The example below creates a window with text and buttons. When clicked, the first two buttons will hide and show the third button. out: layout [ vh2 "Hide Button" body "Hide the extra button." button "Hide It" [hide bt] button "Show It" [show bt] bt: button "Extra Button" ] view out Multiple faces can be provided to HIDE as a block. The block normally contains face object references, but it will also accept the names of variables that hold faces. For example, to remove all of the buttons from the above example, you can hide part of its face pane (a block of faces): hide skip out/pane 2 The SKIP function skips the VH2 and BODY faces in the pane, passing only the BUTTON faces to HIDE. hide [btn1 btn2 txt2] If faces have names, they can be hidden with a block such as: hide [btn1 btn2 txt2] To permanently remove a face from view, remove it from its parent face's pane. In the earlier example the BT button could be permanently removed with: remove find out/pane bt show out The button could be put back with: append out/pane bt show out In both cases, the SHOW is used to refresh the view, showing its changes. Note that for top level faces, HIDE is used by UNVIEW to close windows. In addition, UNVIEW removes the top level face from the screen-face pane. } ] hide-popup [[view] [show-popup inform] { This function is used to hide a popup window that was created with the INFORM or SHOW-POPUP functions. It will hide the most recent popup that has occurred. inform layout [ text bold red "Warning..." button "OK" [hide-popup] ] The above example will display a popup message until the OK button is pressed and the HIDE-POPUP function is evaluated. } ] in-window? [[view] [] { Search all the subfaces of a face to determine if the specified face is within the window. } ] inform [[view] [] { Display a window as a modal dialog. The inform function does not return until the user has finished with the dialog. } ] layout [[view] [view stylize] { The LAYOUT function takes a layout block as an argument and returns a layout face as a result. The block describes the layout according to the rules of the Visual Interface Dialect. The block is evaluated and a face is returned. The result of LAYOUT is can be passed directly to the VIEW function, but it can also be set to a variable or returned as the result of a function. The line: view layout block can also be written as: window: layout block view window The result of the layout function is a face and can be used in other layouts. } ] load-image [[view] [] { When an image is used multiple times, this function allows you to load a single copy into memory and reuse it. Depending on your application, this can save considerable memory. } ] make-face [[view] [] { Make a face based on a face style. The LAYOUT function is not required. img: make-face 'image } ] offset-to-caret [[view] [] { This function is provided to convert from an X-Y offset within a text face to a character index within a string. It is mainly used for text editing and text mapping operations such as for colored or hyperlinked text. Here is an interesting example. When you click your mouse on the upper text face, the string from that position forward will be shown in the lower text face. view layout [ body 80x50 "This is an example string." feel [ engage: func [face act event] [ if act = 'down [ bx/text: copy offset-to-caret face event/offset show bx ] ] ] bx: body 80x50 white black ] When the top face is clicked, the event/offset contains the X-Y offset that is converted to a string index position with offset-to-caret. The string from that point forward is copied and displayed in the lower text box (bx). Note that the string does not have to be displayed for this function to work. Also remember that when making changes to the contents of strings that are longer than 200 characters, you must set the text face line-list to NONE to force the recomputation of all line breaks. } ] alert [[view] [flash] { Post a simple alert message to the user. The only choice for the user is "OK". } ] flash [[view] [alert] { Flash a message to the user. Similar to alert, but without a button. This function is normally used to inform the user of an action as it is occuring. The UNVIEW function can be used to remove the flash. flash "Loading file..." data: load %data.r unview The FLASH function returns the window face that is being displayed, allowing functions such as UNVIEW to explicitly refer to the flash window. fl: flash "Loading..." ... unview/only fl } ] request [[view] [] { Request the user to answer a question. Various refinements allow for a range of answers. The REQUEST function returns TRUE, FALSE, or NONE. TRUE is returned on an affirmative answer, FALSE is returned on a negative answer, and NONE is returned on a cancel operation. request "Do you want to save?" request/confirm "Delete the file?" request/ok "File has been removed." request ["Select action:" "Encrypt" "Decrypt" "Cancel"] } ] request-color [[view] [] { Popup a window that requests a color selection from the user. } ] request-date [[view] [] { Popup a window that contains a calendar to request a date from the user. } ] request-download [[view] [] { Begin downloading a file from a URL and show a progress bar. Return the data of the file as a binary value. The user may cancel the operation at any time, in which case a NONE is returned. } ] request-file [[view] [] { Popup a window to allow the user to select a file. } ] request-list [[view] [] { Popup a window that requests the user pick an item from a list. } ] request-pass [[view] [] { Pop-up a window that requests a username and password from the user. The password is obscured with *'s as it is entered. The result is returned as block that contains two strings. The first string is the username entry, the second is the password. If the user cancels the pop-up, a none is returned. For example: if user-pass: request-pass [ print ["User:" user-pass/1 "Pass:" user-pass/2] ] You can provide a default username with the user refinement: request-pass/user "Fred" To specify a password only, use the /only refinement. To provide a different title for the pop-up, use the /title refinement. } ] request-text [[view] [] { Pop-up a window that requests text from the user. The /title refinement can be used to change the request question: print request-text/title "Enter your name:" If the user presses cancel or closes the window, a NONE is returned. } ] screen-offset? [[view] [] { ??? } ] show [[view] [] { This is a low-level View function that is used to display or update a face. The face being displayed must be part of an active pane (one that is part of a window display). The SHOW function is called frequently to update the display of a face after changes have been made. If the face contains a pane of sub-faces, all of those faces will be redisplayed. If you attempt to show a face and nothing happens, make sure that the face is part of the display hierarchy. That is, the face must be present in the pane list of another face that is being displayed. For example, if you modify any of the attributes of a face, you call the SHOW function to display the change. The code below shows this: view layout [ bx: box 100x24 black button "Red" [bx/color: red show bx] button "Green" [bx/color: green show bx] ] The example below creates a layout face and then removes faces from its pane. The SHOW function is called each time to refresh the face and display what has happened. out: layout [ h1 "Show Example" t1: text "Text 1" t2: text "Text 2" ] view/new out wait 1 remove find out/pane t2 show out wait 1 remove find out/pane t1 show out wait 1 append out/pane t2 show out wait 1 unview } ] show-popup [[view] [] { ??? } ] size-text [[view] [] { Returns the xy size of face text. This function can be used to determine the size of text in advance, allowing code to make adjustments before displaying the text. Note that the face does not need to be shown for this function to work correctly. f: make face [text: "Hello there"] size-text f } ] span? [[view] [] { This function examines all the faces that are provided in a block, and returns the minimum and maximum positions that includes all of those faces. In other words this function returns the rectangle that would enclose all of the faces provided in the block. This is useful if you want to create a special rectangular area that encloses a set of faces. This function returns a block that contains the coordinate pairs of the upper left and lower right bounds. For example: out: layout [h1 "Heading" button "Test"] probe span out/pane } ] stylize [[view] [layout] { This function allows you to define a set of face styles that can be used in multiple layouts. For instance, if you want to define a standard style of text or a standard button style, you can place it in a stylesheet using STYLIZE. The stylesheet can then be used in one or more layouts. Each style is specified in a format that is similar to LAYOUT. The STYLIZE function returns a stylesheet block that can be used in a layout. The code below defines a stylesheet that contains three styles: text-styles: stylize [ big-text: text font-size 50 red-text: text red bold-blue-text: text bold blue font-size 50 ] view layout [ styles text-styles big-text "One big heading..." red-text "This text will appear red." big-bold-blue-text "This is big, bold, and blue." ] Multiple stylesheets can be used in a layout. The stylize function also allows you to modify the master styles for your current REBOL session. However, be careful, as all scripts that are run after modifying the master stylesheet will be affected. } ] textinfo [[view] [] { ??? } ] unfocus [[view] [focus] { Removes the focus from the current focal face. The face was previously specified with the FOCUS function to set it as the focal point for input events. If the face had text highlighted, the highlighting is cleared. out: layout [ h2 "Input your info:" f1: field button "Unfocus" [unfocus] button "Close" [unview] ] focus f1 view out If UNFOCUS is called when there is no focal face, it will be ignored. } ] unview [[view] [view show hide flash inform] { The UNVIEW function is used to close a window previously opened with the VIEW function. By default, the last window that has been opened will be closed. To close a specific window, use the /only refinement and specify the window's face (that which was returned from a layout, for example). All windows can be closed with the /all refinement. The example below opens a window that displays a Close button. Clicking on the button will evaluate the UNVIEW function and the window will be closed. view layout [button "Close" [unview]] Note that the VIEW function will not return until all windows have been closed. (Use VIEW/new to return immediately after the window is opened.) The next example will open two windows, then use UNVIEW/only to close each one separately. out1: layout [button "Close 2" [unview out2]] out2: layout [button "Close 1" [unview out1]] view/new out1 view/new out2 do-events You could have closed both windows with the line: unview/all } ] view [[view] [unview hide show flash inform] { The view function creates and updates windows. It takes a face as its argument. The contents of the window is determined from a face that holds a block of the graphical objects. The window face is normally created with the LAYOUT function, but faces can be constructed directly from face objects and displayed as well. The example below opens a window and displays some text and a button. view layout [ h2 "The time is currently:" h3 form now button "Close" [unview] ] The position and size of the window is determined from the face to be displayed. In the example above, the size of the window is automatically computed by the LAYOUT function. The window is shown in the default position in the upper left area of the screen. The window's caption will be default be the title of the script that is being run. To provide a different caption, use the /title refinement and a string. view/title layout [h1 "Window"] "A Window" The first use of view within an application is special. It displays the window and initializes the graphical interface system. Subsequent calls to VIEW update the window, they do not create new windows unless the /new refinement is provided. view layout [ button "Change" [ view layout [button "Stop" [unview] ] ] The first call to the VIEW function will not return immediately. At that point your code becomes event driven, calling the functions associated with various faces. While the first call to VIEW remains active, any other calls to VIEW will return immediately. The first call will return only after all windows have been closed. Additionally, calls to view can specify options, such as whether the window has borders and is resizable. Single options are provided as a word and multiple options are specified in a block. out: layout [vh1 "This is a window."] view/options out [resize no-title] } ] win-offset? [[view] [] { ??? } ] within? [[view] [] { This function is used to determine if a point is within a graphical area. You provide the position of the point, the upper left corner of the area, and the area's size. The function will return TRUE if the point is within that area, or FALSE otherwise. For example, this returns TRUE because the point 50x50 is within the bounds of the area: print within? 50x50 20x30 200x300 } ] load-prefs [[view] [] { Load user preference settings from the installed base directory. Return a user-prefs object as a result. } ] alter [[??] [] { ?? } ]