| 1 | ---
 | 
| 2 | default_highlighter: oils-sh
 | 
| 3 | in_progress: true
 | 
| 4 | css_files: ../../web/base.css ../../web/manual.css ../../web/toc.css
 | 
| 5 | ---
 | 
| 6 | 
 | 
| 7 | Oil Modules Safely Separate a Program Into Files
 | 
| 8 | ================================================
 | 
| 9 | 
 | 
| 10 | Oil has a minimal module system that is shell-like.
 | 
| 11 | 
 | 
| 12 | - "Modules" is actually a misnomer because they are NOT "modular".  Procs are
 | 
| 13 | modular.  But we use the term since "module" is sometimes associated with
 | 
| 14 | file".
 | 
| 15 | - In contrast to other features, it's very different than Python or JavaScript
 | 
| 16 |   modules, which have multiple global namespaces.
 | 
| 17 | 
 | 
| 18 | The only goal is a little more safety.
 | 
| 19 | 
 | 
| 20 | <div id="toc">
 | 
| 21 | </div>
 | 
| 22 | 
 | 
| 23 | ## An Example
 | 
| 24 | 
 | 
| 25 | Library file.  Top level has `module`, `source`, `const`, and `proc`.
 | 
| 26 | 
 | 
| 27 |     # lib-foo.oil (no shebang line necessary)
 | 
| 28 | 
 | 
| 29 |     module lib-foo.oil || return 0  # module named after file
 | 
| 30 |     source $_this_dir/lib-other
 | 
| 31 | 
 | 
| 32 |     const G_foo = {myvar: 42}
 | 
| 33 | 
 | 
| 34 |     proc foo-proc {
 | 
| 35 |       echo 'hi from foo-proc'
 | 
| 36 |     }
 | 
| 37 | 
 | 
| 38 |     # no main function
 | 
| 39 | 
 | 
| 40 | Executable file.  Top level the same 4, plus `oil-main` at the bottom.
 | 
| 41 | 
 | 
| 42 |     #!/usr/bin/env ysh
 | 
| 43 | 
 | 
| 44 |     # deploy.ysh: Deploy C++ program to a server
 | 
| 45 |     module main || return 0  # executable programs use 'main' guard
 | 
| 46 | 
 | 
| 47 |     source $_this_dir/lib-foo.oil
 | 
| 48 |     source $_this_dir/lib-bar.oil
 | 
| 49 | 
 | 
| 50 |     const DEST_HOST = 'example.com'
 | 
| 51 |     const DEST_USER = 'homer'
 | 
| 52 | 
 | 
| 53 |     proc .private-p {
 | 
| 54 |       echo "I don't want oil-main to find this"
 | 
| 55 |     }
 | 
| 56 | 
 | 
| 57 |     proc _p {
 | 
| 58 |       .private-p  # direct function call
 | 
| 59 |       foo-proc
 | 
| 60 |       echo hi
 | 
| 61 |     }
 | 
| 62 | 
 | 
| 63 |     proc p {
 | 
| 64 |       sudo $0 _p @ARGV  # argv dispatch pattern
 | 
| 65 |     }
 | 
| 66 | 
 | 
| 67 |     oil-main  # dispatch to arguments in this module, except ones beginning with .
 | 
| 68 | 
 | 
| 69 | ## Usage Guidelines
 | 
| 70 | 
 | 
| 71 | - Distinguish between `.oil` files that are executable programs, and those that
 | 
| 72 |   are libraries
 | 
| 73 |   - A `lib-` prefix or a `lib/` dir can make sense, but isn't required
 | 
| 74 | - Every **file** needs a `module` guard
 | 
| 75 | - Use `oil-main`
 | 
| 76 |   - Optional "hide" symbols with `.`
 | 
| 77 | 
 | 
| 78 | Other:
 | 
| 79 | 
 | 
| 80 | - `source` must only be used at the top level.
 | 
| 81 | - When using modules, it's considered bad style to put code at the top level.
 | 
| 82 |   - Either ALL code is at the top level in short script, or NONE of it is.
 | 
| 83 |   - See the [doc on variables](variables.html).
 | 
| 84 | 
 | 
| 85 | ## Recap: Shell Has Separate Namespaces for Functions and Variables
 | 
| 86 | 
 | 
| 87 | TODO:
 | 
| 88 | 
 | 
| 89 | - Proc namespace 
 | 
| 90 | - Var namespace (a stack)
 | 
| 91 | 
 | 
| 92 | The `source` just concatenates both.
 | 
| 93 | 
 | 
| 94 | This is like a Lisp 2.
 | 
| 95 | 
 | 
| 96 | Oil doesn't deviate from this!  It builds some things on top.
 | 
| 97 | 
 | 
| 98 | TODO: See Interpreter state / data model.
 | 
| 99 | 
 | 
| 100 | ## Mechanisms
 | 
| 101 | 
 | 
| 102 | ### Guarded Execution with `module`
 | 
| 103 | 
 | 
| 104 | - Use either `main` or `mylib.oil`
 | 
| 105 | 
 | 
| 106 | ### `$_this_dir` For Imports Relative To the Current File
 | 
| 107 | 
 | 
| 108 | - This lets you move things around, version them, etc.
 | 
| 109 | 
 | 
| 110 | ### The `oil-main` builtin dispatches to procs
 | 
| 111 | 
 | 
| 112 | The `$0` dispatch pattern.
 | 
| 113 | 
 | 
| 114 | ### Shell Options `redefine_{proc,module}` Expose Name Conflicts
 | 
| 115 | 
 | 
| 116 | In batch mode, you'll get errors.
 | 
| 117 | 
 | 
| 118 | But you can iteratively test in interactive mode.
 | 
| 119 | 
 | 
| 120 |     source mymodule.oil  # 'module' guard will be bypassed in interactive mode
 | 
| 121 | 
 | 
| 122 | ## Bundling 
 | 
| 123 | 
 | 
| 124 | ### Oil Source Files
 | 
| 125 | 
 | 
| 126 | TODO / help wanted: Pea.
 | 
| 127 | 
 | 
| 128 | It's nice that we have this "sequential" or concatenative property of code!
 | 
| 129 | Multiple "modules" can go in the same file.
 | 
| 130 | 
 | 
| 131 | Naming convention: `pkg-foo.oil` ?  I don't really think we should have
 | 
| 132 | packages though? 
 | 
| 133 | 
 | 
| 134 | ### With The Oil Interpreter
 | 
| 135 | 
 | 
| 136 | ## Appendix: Related Documents
 | 
| 137 | 
 | 
| 138 | - Variables and Namespaces
 | 
| 139 | - [QSN](qsn.html)
 |