Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search

[ALLY] REBOL Modules Doc

From: carl::rebol::com at: 31-Jul-2000 13:24

--=====================_951290263==_ Content-Type: text/plain; charset="us-ascii" Jim just reminded me that I promised to say a few words about REBOL Modules here on the ally list. I'll do better than that: Here's a short document that describes REBOL modules. Take a look. -Carl --=====================_951290263==_ Content-Type: text/html; charset="us-ascii" Content-Disposition: attachment; filename="modules.html" <html><title>REBOL Modules </title><body><font face="arial,helvetica"><h2>REBOL Modules </h2></font><p><b><pre> REBOL Enhancement Proposal: REP002 Version: 1.0.1 Author: Carl Sassenrath </pre></b> <HR><P><font face="arial,helvetica"><h3>Contents:</h3></font><p><blockquote><font face="arial,helvetica"><B><A HREF="#section-1">1. Overview </A><BR><A HREF="#section-2">2. Context Binding </A><BR><A HREF="#section-3">3. Creating Modules </A><BR><A HREF="#section-4">4. Module Hierarchy </A><BR><A HREF="#section-5">5. Module Reflection </A><BR></B></font></blockquote><HR><A NAME="section-1"></A><p><font face="arial,helvetica"><h3>1. Overview </h3></font><p><blockquote>A REBOL module is an independent context - a namespace. Modules are similar to objects in that they associate variables with values. However, modules extend beyond objects in the following ways: <p> <ul><li>You cannot access the variables of a module unless they have been explicitly exported nor can you access the word list of a module (as in the first of an object). <p> <li>Modules include descriptive blocks that define the module title, date, version, and other reflective information. <p> <li>You can create modules that act as a global environment, shielding the words above it from direct access. <p> <li>Your scripts can be defined as modules. This is specified by script headers. <p> </ul>Also note that like objects, modules can be nested to allow nested contexts. <p> Modules should not be confused with components, which are the plug-in feature-sets of REBOL. However, a component may include one or more modules. <p> </blockquote><HR><A NAME="section-2"></A><p><font face="arial,helvetica"><h3>2. Context Binding </h3></font><p><blockquote>The module design allows for varying degrees of context binding. You can control how free words (non-locals) are bound. <p> <blockquote><table cellspacing=0 border=0><tr><td valign="top" width="80"><B>Strict</B></td><td valign="top">Bind every word to the local frame. The binder will extend the local frame as much as necessary to hold all words. The module is completely encapsulated. </td></tr> <tr><td valign="top" width="80"><B>User</B></td><td valign="top">Every word that is not defined in a previous context will be bound to the local context. This allows users to get to REBOL's predefined words but have all new words bound to the local context. This is how most scripts will operate by default. </td></tr> <tr><td valign="top" width="80"><B>Explicit</B></td><td valign="top">An explicit list of local words is provided for the module. All other free words will be bound to previous frames. </td></tr> <tr><td valign="top" width="80"><B>Implied</B></td><td valign="top">Words that use SET notation at the top block level of the module will be local. All other are bound above. This is the same as object instance variables. This is the default for the MAKE module function. </td></tr> </table></blockquote></blockquote><HR><A NAME="section-3"></A><p><font face="arial,helvetica"><h3>3. Creating Modules </h3></font><p><blockquote>Modules can be created with either the MAKE function or by evaluating scripts that contain module words in their headers. <p> To create a module with MAKE, you must supply a module interface specification block and a body block. The MAKE has the general form: <p> <b><pre> new: make spec body </pre></b> The value returned from MAKE is the new module and it can be assigned to a variable, passed to another function, or returned as the result of a function. <p> <p><font face="arial,helvetica"><i><h4>3.1. Interface Specification </h4></i></font><p>The specification block is a header that is similar to that used with scripts. It contains a title, date, version, author, and other fields of a header. In addition, there are fields that are unique to modules: <p> <blockquote><table cellspacing=0 border=0><tr><td valign="top" width="80"><B>export</B></td><td valign="top">Provides a block of words that define the variables that can be accessed externally from the module. </td></tr> <tr><td valign="top" width="80"><B>import</B></td><td valign="top">Provides an optional block of imported words. When this block has been provided, no external words are bound within the module other than those that have been specified. This allows you to limit the module's access to REBOL functions. </td></tr> <tr><td valign="top" width="80"><B>local</B></td><td valign="top">Specifies an optional block that explicitly defines the local variables of the module. If this is not specified, then the local variables will be defined by their top level block set operations (as done with objects). </td></tr> <tr><td valign="top" width="80"><B>module-options</B></td><td valign="top">special flags used to control the level of binding for the module. For instance, the LOCAL attribute forces free variables that are not bound in any frame to be bound in the module, not bound in parent contexts. The USER attribute makes the module a top level frame (like a user frame). </td></tr> </table></blockquote>Here is an example of a simple module definition: <p> <b><pre> example: make module! [ title: "Example module" version: 1.0.0 export: [do-it] ][ data: [block of local data] do-it: does [probe data] ] </pre></b> The do-it function can now be called with: <p> <b><pre> example/do-it </pre></b> But, you cannot access the data. This line would cause an error: <p> <b><pre> example/data ** Script Error: Invalid path value: data ** Where: example/data </pre></b> <p><font face="arial,helvetica"><i><h4>3.2. Scripts as Modules </h4></i></font><p>For convenience, a script can also be defined as a module. This is done by specifying the module description as part of the script header: <p> <b><pre> REBOL. [ title: "Script Module" version: 1.0.0 module: 'script-module export: [do-it] ] ... </pre></b> When the script is evaluated, it will be evaluated as a module. All of its free words (globals) will be local to the module. <p> <p><font face="arial,helvetica"><i><h4>3.3. Variable Definitions </h4></i></font><p>Within a module, variables are defined as module-local in the same way that objects define their instance variables. You can write: <p> <b><pre> make module! [export [a]] [ a: b: c: d: e: f: none ... ] </pre></b> You can explicitly declare the variables that are local to a module (but you will also need to remember to maintain this list!): <p> <b><pre> make module! [export [a] local [a b c d e f]] [ ... ] </pre></b> All such locals will be set to NONE when the module is created. <p> Of course, if the LOCAL module-option is used, then all variables will be bound locally other than those that are explicitly imported. <p> </blockquote><HR><A NAME="section-4"></A><p><font face="arial,helvetica"><h3>4. Module Hierarchy </h3></font><p><blockquote>The new module architecture allows an enhanced context structure for REBOL and its scripts. Scripts will no longer be bound by default to the global frame (main-frame). Instead, scripts will be bound to a USER frame that is created below the main frame. This allows entire scripts and all of their functions and data to be garbage collected if they are no longer required. <p> This changes the binding process for scripts. The binder looks locally for a word, then looks up the hierarchy for the name. If the word does not appear anywhere in the hierarchy, then the module frame is extended with the new word. Effectively, free variables become module local, rather than global. <p> The hierarchy of module contexts is now defined as: <p> <b><pre> ROOT frame (natives, and C code references) SYSTEM frame (most of the mezz functions) USER frame (user script) MODULE frame (sub-scripts or make modules) </pre></b> When the USER module-option is used with MAKE, a peer frame is created to a script. The new module is placed at the USER frame level, rather than at the MODULE level. This allows you to create scripts that evaluate scripts in pristine environments. (That is, in the same environment as your first script.) <p> <b><pre> </pre></b> </blockquote><HR><A NAME="section-5"></A><p><font face="arial,helvetica"><h3>5. Module Reflection </h3></font><p><blockquote>You can obtain the header specification of a module with the FIRST function. This will return the header as was used to define the module. This also allows you to reflectively determine what words are exported by a module. You can use this to automatically generate documentation about a module. <p> <b><pre> foreach word get in first module 'export [ print word ] </pre></b> </blockquote>-End: Makespec 1.4.0</body></html> --=====================_951290263==_--