Making modules: the code
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...ā¤Ā»
Documentation about Modules
Making Modules: The Code (this page)
Want to distribute your modules?