Modules, Packages and Exporting

40.1 Writing a Module

# lib/Math/Utils.rakumod
unit module Math::Utils;                  # the rest of the file is the module

sub square(Numeric $x) is export { $x ** 2 }                  # exported by default
sub cube(Numeric $x) is export(:extra) { $x ** 3 }           # exported with the :extra tag
sub helper { 'not exported' }                                 # private to the module
our sub accessible { 'call as Math::Utils::accessible' }      # package-scoped
constant GOLDEN is export = (1 + 5.sqrt) / 2;

class Vector is export {                  # export a class (classes are global by name anyway)
    has $.x; has $.y;
}
# main.raku
use lib 'lib';                            # add lib/ to the module search path
use Math::Utils;                          # imports default exports
use Math::Utils :extra;                   # also imports :extra tagged symbols
say square(4), ' ', cube(2), ' ', GOLDEN;
say Math::Utils::accessible();

40.2 use, need, require and import

import Module Compile time (already loaded) require Module No (unless listed)

my $json-module = 'JSON::Fast';
require ::($json-module);                 # dynamic runtime loading
my &to-json = ::($json-module ~ '::&to-json');
try require Optional::Module;             # optional dependency
use JSON::Fast:ver<0.19+>:auth<zef:timo>; # version and authority constraints

40.3 Custom EXPORT and Packages

# Fine-grained exports with sub EXPORT
sub EXPORT(*@args) {
    Map.new: '&greet' => sub ($n) { "Hi $n" }, '$CONFIG' => @args.head // 'default';
}

package Utils { our sub helper { 'helper' } }   # plain package (namespace without module semantics)
module Tools { }                                # module: package + export capabilities
say Utils::helper();