Home Explore Blog CI



nushell

7th chunk of `book/modules/creating_modules.md`
ca3d45f66180b3721a828391e437a0b4ef089d11c75284d80000000100000c0b
As mentioned above, definitions in a module without the [`export`](/commands/docs/export.md) keyword are only accessible in the module's scope.

To demonstrate, create a new module `is-alphanumeric.nu`. Inside this module, we'll create a `str is-alphanumeric` command. If any of the characters in the string are not alpha-numeric, it returns `false`:

```nu
# is-alphanumeric.nu
def alpha-num-range [] {
    [
        ...(seq char 'a' 'z')
        ...(seq char 'A' 'Z')
        ...(seq 0 9 | each { into string })
    ]
}

export def "str is-alphanumeric" []: string -> bool {
    if ($in == '') {
        false
    } else {
        let chars = (split chars)
        $chars | all {|char| $char in (alpha-num-range)}
    }
}
```

Notice that we have two definitions in this module -- `alpha-num-range` and `str is-alphanumeric`, but only the second is exported.

```nu
use is-alphanumeric.nu *
'Word' | str is-alphanumeric
# => true
'Some punctuation?!' | str is-alphanumeric
# => false
'a' in (alpha-num-range)
# => Error:
# => help: `alpha-num-range` is neither a Nushell built-in or a known external command
```

### Selective Export from a Submodule

::: note
While the following is a rare use-case, this technique is used by the Standard Library to
make the `dirs` commands and its aliases available separately.
:::

As mentioned in the [Submodules](#submodules) section above, only `export use` can selectively export definitions from a submodule.

To demonstrate, let's add a modified form of the `go.nu` module example [above](#caveats) to `my-utils`:

```nu
# go.nu, in the my-utils directory
export def --env home [] {
    cd ~
}

export def --env modules [] {
    cd ($nu.default-config-dir | path join "scripts")
}

export alias h = home
export alias m = modules
```

This `go.nu` includes the following changes from the original:

- It doesn't rely on the `my-utils` mod since it will now be a submodule of `my-utils` instead
- It adds "shortcut" aliases:
  `h`: Goes to the home directory (alias of `go home`)
  `m`: Goes to the modules directory (alias of `go modules`)

A user could import _just_ the aliases with:

```nu
use my-utils/go.nu [h, m]
```

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:

```nu
export use ./go.nu [home, modules]
```

That _almost_ works -- It selectively exports `home` and `modules`, but not the aliases. However, it does so without the `go` prefix. For example:

```nu
use my-utils *
home
# => works
go home
# => Error: command not found
```

To export them as `go home` and `go modules`, make the following change to `my-utils/mod.nu`:

```nu
# Replace the existing `export use` with ...
export module go {
    export use ./go.nu [home, modules]
}
```

This creates a new, exported submodule `go` in `my-utils` with the selectively (re)exported definitions for `go home` and `go modules`.

```nu
use my-utils *
# => As expected:
go home
# => works
home
# => Error: command not found
```

Title: Module Scoping and Selective Export from Submodules
Summary
This chunk illustrates module scoping in Nushell, showing how to define internal functions (`alpha-num-range`) that are not accessible outside the module unless exported. It then explains how to selectively export commands from a submodule. Using a `go.nu` submodule within `my-utils`, it demonstrates exporting only the `home` and `modules` commands, but not the aliases, and then shows how to use `export module` to re-export them under the `go` submodule namespace, resulting in `go home` and `go modules` commands being available when `my-utils` is imported.