Course of Raku / Advanced / Modules
Module introspection
A module’s name introduces a package — a namespace that
holds the names defined in it. Earlier, in the section about containers, you met
WHO, which returns the Stash (the symbol
table) of a package. Module introspection puts that to use.
The examples below use the Greeting module built up in
the earlier topics — an exported subroutine and a shared
our variable:
unit module Greeting;
our $version = '1.0';
sub hello($name) is export {
return "Hello, $name!";
}The package of a module is written with a trailing ::.
Adding .keys lists the names it contains:
use Greeting;
say Greeting::.keys.sort; # ($version EXPORT)The Greeting module from the earlier topics defines an
our variable, $version, so its package
contains that name — with the sigil included. Next to it sits
EXPORT, which may look surprising. It is a package Raku
creates automatically to hold everything a module marks
is export, such as the hello subroutine. An
exported name therefore does not appear directly in the
package; it lives inside that EXPORT sub-package. (The keys
come back in no fixed order, so the example sorts them for a stable
result.)
You can also look a name up in the package by using it as a key. This
reaches the same value as the qualified
$Greeting::version:
use Greeting;
say Greeting::{'$version'}; # 1.0Listing what a module exports
The EXPORT package seen above is where the exported
names actually live, so you can list them by looking one level deeper.
Exports without a tag go into the DEFAULT group (see Export tags), and its
.keys are the exported routines:
use Greeting;
say Greeting::EXPORT::DEFAULT::.keys.sort; # (&hello)Each key is an exported name with its sigil — here the single
subroutine &hello, shown with the &
that marks a routine. This is how you discover what a module makes
available to its users without reading its source: ask its
EXPORT::DEFAULT package what it holds.
Introspecting a package this way is handy when you want to discover what a module provides, or to reach its names dynamically rather than writing each one out in the source code.
Practice
Complete the quiz that covers the contents of this topic.
Exercises
This section contains 2 exercises. Examine all the topics of this section before doing the coding practice.