Module packages

Creating module packages for code reuse

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...ā¤Ā»

See Also

Classes and objects

A tutorial about creating and using classes in Raku

CompUnits and where to find them

How and when Raku modules are compiled, where they are stored, and how to access them in compiled form.

Concurrency

Concurrency and asynchronous programming

Command line interface

Creating your own CLI in Raku

Grammar tutorial

An introduction to grammars

Input/Output

File-related operations

Inter-process communication

Programs running other programs and communicating with them

Iterating

Functionalities available for visiting all items in a complex data structure

Doing math with Raku

Different mathematical paradigms and how they are implemented in this language

Core modules

Core modules that may be useful to module authors

Module development utilities

What can help you write/test/improve your module(s)

Modules

How to create, use, and distribute Raku modules

Creating operators

A short tutorial on how to declare operators and create new ones.

Regexes: best practices and gotchas

Some tips on regexes and grammars

REPL

Read-eval-print loop

Entering unicode characters

Input methods for unicode characters in terminals, the shell, and editors

The Camelia image is copyright 2009 by Larry Wall. "Raku" is trademark of the Yet Another Society. All rights reserved.