How the R3 Chat reblet gets built
Sometimes you want to read something a bit more technical on this blog, right? Maybe a bit of code?
Well, those of you who use R3 know that it has a forum reblet that can be run by typing chat at the prompt. The app runs in the console, so it's a bit old school, but it allows message threads, topics, alerts, file sharing, accounts, permissions, user ranking... 50 commands over all. (You can view a mobile web page interface to it at REBOL R3 Chat.)
When you type chat, the reblet gets downloaded from our web server. The download is 22 KB, smaller than most web pages these days.
For those new to REBOL, I thought I'd take a minute to describe how we "develop and deploy" this app... to use "enterprisy" language.
For development and debugging, we have a small "main" script whose purpose is to setup the primary configuration variables then load ten other source files and start the app. We use this for debugging because it's easy to modify the various files and test them, just like any other REBOL script.
The main file basically looks like this:
REBOL [ Title: "RebDev Command Line Interface" Author: "Carl Sassenrath" Version: 0.4.19 Needs: 2.100.28 Date: 31-Dec-2008 ] do %rc-funcs.r client-version: 0.4.0 verbose: false ... ; some config code do %rc-help.r do %rc-defs.r do %rc-data.r do %rc-user.r do %rc-show.r do %rc-link.r do %r3-pass.r do %rc-comm.r do %rc-file.r do %rc-cmds.r start-chat
Once we've got it working, we're ready to build the release file. To do that, we merge all the source files and compress the result. We paste on a new header and a decompression line, and it's ready for upload to our server. (Of course, this is just one way of doing it. A variety of techniques are available from other REBOLers in the community.)
Here are the two function we use for building it. While small and simple, they do require deeper knowledge of REBOL, so that's why I'm providing them here.... for new users who want to try this with their own code.
This function loads the main program of the chat client then merges each of the source files.
load-all-code: funct [ "Given a main program file, load it and merge all to-level DO files." file ][ out: code: load/all file while [out: find out 'do][ either file? file: out/2 [ change/part out load file 2 ][out: next out] ] code ]
This function takes the code loaded above, molds it (without indentation), compresses it, then builds a new header and inserts the binary below it.
compress-code: funct [ "Write out the compressed code file." code [block!] ][ ; Grab code header: remove code ; REBOL word header: take code ; Wrap all the code in a context: code: compose/only [your-app: context (code)] ;save %src-code.r code ; uncomment to see result code: compress mold/only/flat code ; Extend the header with date and checksum: append header compose [ Date: (now/date) Check: (checksum/secure code) Note: "To see the source, change DO to PROBE below." ] ; Return result with header and compressed body: trim/head mold/only compose/deep [ REBOL [(header)] do load decompress (code) ] ]
Notice that the new header is built to include the current date and also an SHA1 hash checksum which will be validated by R3 when it loads this file.
Also, note that all your code is wrapped in a context called your-app. That's done to give your global variables their own private storage. If your code wants to export some functions, you'll need to use set on them, or better yet, change this code to make it a module with an export list. (That's also for another day.)
To put it all together, we call the functions above like this:
system/options/binary-base: 64 code: load-all-code %rc-main.r code: compress-code code print ["File size:" length? code] write %chat.r code ; converts to UTF-8
This chat.r file is now ready to be uploaded to our web server. Actually, we use just a few more lines of code to do that, but that code deserves another article.
Keep in mind that this code was written for R3... kind of a nudge to get you headed that way. A few lines of it are not compatible with R2; however, the codes is easily adapted.