Module packages
N.B. "Module" is an overloaded term in Raku; this document
focuses on use of the module
declarator.
What are modules?
Modules, like classes and grammars, are a kind of
package. Module objects are instances of the
ModuleHOW
metaclass; this provides certain capabilities useful for
creating namespaces, versioning, delegation and data encapsulation (see
also class and role).
To create a module, use the module
declarator:
module M {}
say M.HOW; # OUTPUT: Ā«Perl6::Metamodel::ModuleHOW.newā¤Ā»
Here we define a new module named M
; introspection with HOW
confirms that the metaclass underlying M
is
Perl6::Metamodel::ModuleHOW
.
When to use modules
Modules are primarily useful for encapsulating code and data that
do not belong inside a class or role definition. Module contents
(classes, subroutines, variables, etc.) can be exported from a
module with the is export
trait; these are available in the
caller's namespace once the module has been imported with import
or use
. A module can also selectively expose symbols within its
namespace for qualified reference via our
.
Working with modules
To illustrate module scoping and export rules, let's begin by
defining a simple module M
:
module M {
sub greeting ($name = 'Camelia') { "Greetings, $name!" }
our sub loud-greeting (--> Str) { greeting().uc }
sub friendly-greeting is export { greeting('friend') }
}
Recall that subroutines are lexically scoped unless otherwise specified
(declarator sub is equivalent to my sub
), so
greeting
in the above example is lexically scoped to the module and
inaccessible outside of it. We've also defined loud-greeting
with the
our
declarator, which means that in addition to being lexically
scoped it is aliased in the module's symbol table. Finally,
friendly-greeting
is marked for export; it will be registered in the
caller's symbol table when the module is imported:
import M; # import the module
say M::loud-greeting; # OUTPUT: Ā«GREETINGS, CAMELIA!ā¤Ā»
say friendly-greeting; # OUTPUT: Ā«Greetings, friend!ā¤Ā»
Modules on disk
While .raku
and .rakumod
files are sometimes
referred to as "modules", they are really just normal files that
are loaded and compiled when you write need
, use
or require
.
For a .rakumod
file to provide a module in the sense that we've been
using, it needs to declare one with module
as documented above.
For example, by placing module M
inside Foo.rakumod
, we can load
and use the module as follows:
use Foo; # find Foo.rakumod, run need followed by import
say M::loud-greeting; # OUTPUT: Ā«GREETINGS, CAMELIA!ā¤Ā»
say friendly-greeting; # OUTPUT: Ā«Greetings, friend!ā¤Ā»
Note the decoupling between file and module namesāa .rakumod
file
can declare zero or more modules with arbitrary identifiers.
File and module naming
Often we want a .rakumod
file to provide a single module and
nothing more. Here a common convention is for the file basename to
match the module name. Returning to Foo.rakumod
, it is apparent that
it only provides a single module, M
; in this case, we might want
to rename M
to Foo
. The amended file would then read:
module Foo {
sub greeting ($name = 'Camelia') { "Greetings, $name!" }
our sub loud-greeting (--> Str) { greeting().uc }
sub friendly-greeting is export { greeting('friend') }
}
which can be used more consistently by the caller (note the
relationship between the use Foo
and Foo::
):
use Foo;
say Foo::loud-greeting; # OUTPUT: Ā«GREETINGS, CAMELIA!ā¤Ā»
say friendly-greeting; # OUTPUT: Ā«Greetings, friend!ā¤Ā»
If Foo.rakumod
is placed deeper within the source tree, e.g. at
lib/Utils/Foo.rakumod
, we can elect to name the module Utils::Foo
to maintain consistency.
The unit
keyword
Files that only provide a single module can be written more concisely
with the unit
keyword; unit module
specifies that the
rest of the compilation unit is part of the declared module. Here's
Foo.rakumod
rewritten with unit
:
unit module Foo;
sub greeting ($name = 'Camelia') { "Greetings, $name!" }
our sub loud-greeting (--> Str) { greeting().uc }
sub friendly-greeting is export { greeting('friend') }
Everything following the unit declaration is part of the Foo
module specification.
(Note that unit
can also be used with class
, grammar
and
role
.)
What happens if I omit module
?
To better understand what the module
declarator is doing in
Foo.rakumod
, let's contrast it with a variant file, Bar.rakumod
, that
omits the declaration. The subroutine definitions below are almost
identical (the only difference is in the body of greeting
,
modified for clarity):
sub greeting ($name = 'Camelia') { "Greetings from Bar, $name!" }
our sub loud-greeting (--> Str) { greeting().uc }
sub friendly-greeting is export { greeting('friend') }
As a reminder, here's how we used Foo.rakumod
before,
use Foo;
say Foo::loud-greeting; # OUTPUT: Ā«GREETINGS, CAMELIA!ā¤Ā»
say friendly-greeting; # OUTPUT: Ā«Greetings, friend!ā¤Ā»
and here's how we use Bar.rakumod
,
use Bar;
say loud-greeting; # OUTPUT: Ā«GREETINGS FROM BAR, CAMELIA!ā¤Ā»
say friendly-greeting; # OUTPUT: Ā«Greetings from Bar, friend!ā¤Ā»
Note the use of loud-greeting
rather than Bar::loud-greeting
as Bar
is not a known symbol (we didn't create a module
of
that name in Bar.rakumod
). But why is loud-greeting
callable even
though we didn't mark it for export? The answer is simply that
Bar.rakumod
doesn't create a new package namespaceā$?PACKAGE
is
still set to GLOBAL
āso when we declare loud-greeting
as our
,
it is registered in the GLOBAL
symbol table.
Lexical aliasing and safety
Thankfully, Raku protects us from accidentally clobbering call
site definitions (e.g. builtins). Consider the following addition
to Bar.rakumod
:
our sub say ($ignored) { print "oh dear\n" }
This creates a lexical alias, hiding the say
builtin inside
Bar.rakumod
but leaving the caller's say
unchanged. Consequently,
the following call to say
still works as expected:
use Bar;
say 'Carry on, carry on...'; # OUTPUT: Ā«Carry on, carry on...ā¤Ā»