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)
|