Skip to content

Commit 0696d6e

Browse files
authored
Address feedback from #1597 review (#1620)
1 parent 30cdd54 commit 0696d6e

File tree

3 files changed

+116
-19
lines changed

3 files changed

+116
-19
lines changed

book/modules/creating_modules.md

Lines changed: 84 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ In the [Basic Example](#basic-module-example) above, we had a module named `inc`
6969
```nu
7070
mv inc.nu increment.nu
7171
use increment.nu *
72-
7372
# => Error: nu::parser::named_as_module
7473
# => ...
7574
# => help: Module increment can't export command named
@@ -120,10 +119,10 @@ Additionally, `main` has special behavior if used in a script file, regardless o
120119
121120
As mentioned briefly in the Overview above, modules can be created either as:
122121
123-
* `<module_name>.nu`: Useful for simple modules
124-
* `<module_name>/mod.nu`: Useful for organizing larger module projects where submodules can easily map to subdirectories of the main module
122+
1. `<module_name>.nu`: "File-form" - Useful for simple modules
123+
2. `<module_name>/mod.nu`: "Directory-form" - Useful for organizing larger module projects where submodules can easily map to subdirectories of the main module
125124
126-
The `increment.nu` example above is clearly an example of the former. Let's convert it to the directory form:
125+
The `increment.nu` example above is clearly an example of (1) the file-form. Let's try converting it to the directory-form:
127126
128127
```nu
129128
mkdir increment
@@ -152,7 +151,7 @@ export def main []: int -> int {
152151
}
153152
154153
export def "increment by" [amount: int]: int -> int {
155-
$in + $amount
154+
$in + $amount
156155
}
157156
```
158157

@@ -166,7 +165,7 @@ export def main []: int -> int {
166165
}
167166
168167
export def by [amount: int]: int -> int {
169-
$in + $amount
168+
$in + $amount
170169
}
171170
```
172171

@@ -183,10 +182,7 @@ Submodules are modules that are exported from another module. There are two ways
183182
1. With `export module`: Exports (a) the submodule and (b) its definitions as members of the submodule
184183
2. With `export use`: Exports (a) the submodule and (b) its definitions as members of the parent module
185184

186-
To demonstrate the difference, let's add to our `increment` example by:
187-
188-
- Adding a new `range-into-list` module and command
189-
- Creating a new parent module `my-utils` with `increment` and `range-into-list` as its submodules
185+
To demonstrate the difference, let's create a new `my-utils` module, with our `increment` example as a submodule. Additionally, we'll create a new `range-into-list` command in its own submodule.
190186

191187
1. Create a directory for the new `my-utils` and move the `increment.nu` into it
192188

@@ -277,6 +273,10 @@ ls / | sort-by modified | select ...$file_indices
277273

278274
Run `scope modules` again and notice that all of the commands from the submodules are re-exported into the `my-utils` module.
279275

276+
::: tip
277+
While `export module` is the recommended and most common form, there is one module-design scenario in which `export use` is required -- `export use` can be used to _selectively export_ definitions from the submodule, something `export module` cannot do. See [Additional Examples - Selective Export](#selective-export-from-a-submodule) for an example.
278+
:::
279+
280280
::: note
281281
`module` without `export` defines only a local module; it does not export a submodule.
282282
:::
@@ -471,3 +471,77 @@ use is-alphanumeric.nu *
471471
# => Error:
472472
# => help: `alpha-num-range` is neither a Nushell built-in or a known external command
473473
```
474+
475+
### Selective Export from a Submodule
476+
477+
::: note
478+
While the following is a rare use-case, this technique is used by the Standard Library to
479+
make the `dirs` commands and its aliases available separately.
480+
:::
481+
482+
As mentioned in the [Submodules](#submodules) section above, only `export use` can selectively export definitions from a submodule.
483+
484+
To demonstrate, let's add a modified form of the `go.nu` module example [above](#caveats) to `my-utils`:
485+
486+
```nu
487+
# go.nu, in the my-utils directory
488+
export def --env home [] {
489+
cd ~
490+
}
491+
492+
export def --env modules [] {
493+
cd ($nu.default-config-dir | path join "scripts")
494+
}
495+
496+
export alias h = home
497+
export alias m = modules
498+
```
499+
500+
This `go.nu` includes the following changes from the original:
501+
502+
- It doesn't rely on the `my-utils` mod since it will now be a submodule of `my-utils` instead
503+
- It adds "shortcut" aliases:
504+
`h`: Goes to the home directory (alias of `go home`)
505+
`m`: Goes to the modules directory (alias of `go modules`)
506+
507+
A user could import _just_ the aliases with:
508+
509+
```nu
510+
use my-utils/go.nu [h, m]
511+
```
512+
513+
However, let's say we want to have `go.nu` be a submodule of `my-utils`. When a user imports `my-utils`, they should _only_ get the commands, but not the aliases. Edit `my-utils/mod.nu` and add:
514+
515+
```nu
516+
export use ./go.nu [home, modules]
517+
```
518+
519+
That _almost_ works -- It selectively exports `home` and `modules`, but not the aliases. However, it does so without the `go` prefix. For example:
520+
521+
```nu
522+
use my-utils *
523+
home
524+
# => works
525+
go home
526+
# => Error: command not found
527+
```
528+
529+
To export them as `go home` and `go modules`, make the following change to `my-utils/mod.nu`:
530+
531+
```nu
532+
# Replace the existing `export use` with ...
533+
export module go {
534+
export use ./go.nu [home, modules]
535+
}
536+
```
537+
538+
This creates a new, exported submodule `go` in `my-utils` with the selectively (re)exported definitions for `go home` and `go modules`.
539+
540+
```nu
541+
use my-utils *
542+
# => As expected:
543+
go home
544+
# => works
545+
home
546+
# => Error: command not found
547+
```

book/modules/using_modules.md

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ The path to the module can be:
4747
::: details Example
4848

4949
```nu
50-
use ~/nushell/modules/nupm`
50+
use ~/nushell/modules/nupm
5151
```
5252

5353
Note that the module name (its directory) can end in a `/` (or `\` on Windows), but as with most commands that take a paths (e.g., `cd`), this is completely optional.
@@ -69,7 +69,7 @@ The path to the module can be:
6969
Note that the module name (its directory) can end in a `/` (or `\` on Windows), but as with most commands that take a paths (e.g., `cd`), this is completely optional.
7070
:::
7171

72-
::: important Important! Importing modules from `$env.NU_LIB_PATH`
72+
::: important Important! Importing modules from `$env.NU_LIB_DIRS`
7373
When importing a module via a relative path, Nushell first searches from the current directory. If a matching module is not found at that location, Nushell then searches each directory in the `$env.NU_LIB_DIRS` list.
7474

7575
This allows you to install modules to a location that is easily accessible via a relative path regardless of the current directory.
@@ -104,7 +104,9 @@ The path to the module can be:
104104

105105
### Module Definitions
106106

107-
The second argument to the `use` command is an optional list of the definitions to import. Again, the module documentation should provide recommendations, but you always have the option to choose a form that works best for your use-case.
107+
The second argument to the `use` command is an optional list of the definitions to import. Again, the module documentation should provide recommendations. For example, the [Standard Library Chapter](../standard_library.md#importing-submodules) covers the recommended imports for each submodule.
108+
109+
Of course, you always have the option to choose a form that works best for your use-case.
108110

109111
- **Import an entire module/submodule as a command with subcommands**
110112

@@ -135,9 +137,7 @@ The second argument to the `use` command is an optional list of the definitions
135137

136138
Notice how the `to jsonl` command is placed directly in the current scope, rather than being a subcommand of `formats`.
137139

138-
The [Standard Library Chapter](../standard_library.md) covers the recommended imports for each submodule.
139-
140-
- **Import one or more commands from a module**
140+
- **Import one or more definitions from a module**
141141

142142
Nushell can also selectively import a subset of the definitions of a module. For example:
143143

@@ -161,16 +161,39 @@ The second argument to the `use` command is an optional list of the definitions
161161
use std/formats [ 'from ndjson' 'to ndjson' ]
162162
```
163163

164+
::: note Importing submodules
165+
While you can import a submodule by itself using `use <module> </submodule>` (e.g., `use std help`), the entire parent module and _all_ of its definitions (and thus submodules) will be _parsed_ when using this form. When possible, loading the submodule as a _module_ will result in faster code. For example:
166+
167+
```nu
168+
# Faster
169+
use std/help
170+
```
171+
172+
:::
173+
164174
## Importing Constants
165175

166-
As seen above with the `std/math` examples, some modules may export constant definitions. The syntax for accessing a constant varies slightly depending on how it was imported. For example:
176+
As seen above with the `std/math` examples, some modules may export constant definitions. When importing the entire module, constants can be accessed through a record with the same name as the module:
167177

168178
```nu
179+
# Importing entire module - Record access
169180
use std/math
170181
$math.PI
171-
# or
182+
# => 3.141592653589793
183+
184+
$math
185+
# => ╭───────┬──────╮
186+
# => │ GAMMA │ 0.58 │
187+
# => │ E │ 2.72 │
188+
# => │ PI │ 3.14 │
189+
# => │ TAU │ 6.28 │
190+
# => │ PHI │ 1.62 │
191+
# => ╰───────┴──────╯
192+
193+
# Or importing all of the module's members
172194
use std/math *
173195
$PI
196+
# => 3.141592653589793
174197
```
175198

176199
## Hiding

book/standard_library.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ use std formats *
9393
```
9494

9595
::: important
96-
However, similar to `use std *`, this form first loads the _entire_ Standard Library into scope and _then_ imports the submodules. In contrast, the slash-separated versions in #1 and #2 above _only_ import the submodule and will be much faster as a result.
96+
As mentioned in [Using Modules](./modules/using_modules.md#module-definitions), this form (like `use std *`) first loads the _entire_ Standard Library into scope and _then_ imports the submodules. In contrast, the slash-separated versions in #1 and #2 above _only_ import the submodule and will be much faster as a result.
9797
:::
9898

9999
## The Standard Library Candidate Module

0 commit comments

Comments
 (0)