Packages

Organizing and referencing namespaced program elements

Packages are nested namespaces of named program elements. Modules, classes, grammars, and others are types of packages. Like files in a directory, you can generally refer to named elements with their short-name if they are local, or with the longer name that includes the namespace to disambiguate as long as their scope allows that.

Names

A package name is anything that is a legal part of a variable name (not counting the sigil). This includes:

class Foo {
    sub zape () { say "zipi" }
    class Bar {
        method baz () { return 'Þor is mighty' }
        our &zape = { "zipi" };
        our $quux = 42;
    }
}

my $foo;                # simple identifiers
say Foo::Bar.baz;       # calling a method; OUTPUT: «Þor is mighty␤»
say Foo::Bar::zape;     # compound identifiers separated by ::; OUTPUT: «zipi␤»
my $bar = 'Bar';
say $Foo::($bar)::quux; # compound identifiers with interpolations; OUTPUT: «42␤»
$42;                    # numeric names
$!;                     # certain punctuation variables

:: is used to separate nested package names.

Packages do not really have an identity; they can be simply part of a module or class name, for instance. They are more similar to namespaces than to modules. A module of the same name will capture the identity of a package if it exists.

package Foo:ver<0> {};
module Foo:ver<1> {};
say Foo.^ver; # OUTPUT: «1␤»

The syntax allows the declared package to use a version as well as an authority auth, but as a matter of fact, it's dismissed; only modules, classes and other higher order type objects have an identity that might include auth and ver.

package Foo:ver<0>:auth<bar> {};
say Foo.^auth;
# OUTPUT: «(exit code 1) No such method 'auth' for invocant of type
# 'Perl6::Metamodel::PackageHOW' ...

Package-qualified names

Ordinary package-qualified names look like this: $Foo::Bar::quux, which would be the $quux variable in package Foo::Bar; Foo::Bar::zape would represent the &zape variable in the same package.

Sometimes it's clearer to keep the sigil with the variable name, so an alternate way to write this is:

Foo::Bar::<$quux>

This does not work with the Foo«&zape» variable, since subs, by default, have lexical scope. The name is resolved at compile time because the variable name is a constant. We can access the rest of the variables in Bar (as shown in the example above) since classes, by default, have package scope.

If the name part before :: is null, it means the package is unspecified and must be searched for. Generally this means that an initial :: following the main sigil is a no-op on names that are known at compile time, though ::() can also be used to introduce an interpolation. Also, in the absence of another sigil, :: can serve as its own sigil indicating intentional use of a not-yet-declared package name.

Pseudo-packages

|Reference,MY (package)|Reference,OUR (package)|Reference,CORE (package)|Reference,GLOBAL (package)|Reference,PROCESS (package)|Reference,COMPILING(package) The following pseudo-package names are reserved at the front of a name:

MY Symbols in the current lexical scope (aka $?SCOPE)
OUR Symbols in the current package (aka $?PACKAGE)
CORE Outermost lexical scope, definition of standard Raku
GLOBAL Interpreter-wide package symbols, really UNIT::GLOBAL
PROCESS Process-related globals (superglobals). The last place dynamic variable lookup will look.
COMPILING Lexical symbols in the scope being compiled

|Reference,CALLER (package)|Reference,CALLERS (package)|Reference,DYNAMIC (package) |Reference,OUTER (package)|Reference,OUTERS (package)|Reference,LEXICAL (package) |Reference,UNIT (package)|Reference,SETTING (package)|Reference,PARENT (package)|Reference,CLIENT (package) The following relative names are also reserved but may be used anywhere in a name:

CALLER Dynamic symbols in the immediate caller's lexical scope
CALLERS Dynamic symbols in any caller's lexical scope
DYNAMIC Dynamic symbols in my or any caller's lexical scope
OUTER Symbols in the next outer lexical scope
OUTERS Symbols in any outer lexical scope
LEXICAL Dynamic symbols in my or any outer's lexical scope
UNIT Symbols in the outermost lexical scope of compilation unit
SETTING Lexical symbols in the unit's DSL (usually CORE)
PARENT Symbols in this package's parent package (or lexical scope)
CLIENT The nearest CALLER that comes from a different package

The file's scope is known as UNIT, but there are one or more lexical scopes outside of that corresponding to the linguistic setting (often known as the prelude in other cultures). Hence, the SETTING scope is equivalent to UNIT::OUTERS. For a standard Raku program SETTING is the same as CORE, but various startup options (such as -n or -p) can put you into a domain specific language, in which case CORE remains the scope of the standard language, while SETTING represents the scope defining the DSL that functions as the setting of the current file. When used as a search term in the middle of a name, SETTING includes all its outer scopes up to CORE. To get only the setting's outermost scope, use UNIT::OUTER instead.

Looking up names

Interpolating into names

You may interpolate a string into a package or variable name using ::($expr) where you'd ordinarily put a package or variable name. The string is allowed to contain additional instances of ::, which will be interpreted as package nesting. You may only interpolate entire names, since the construct starts with ::, and either ends immediately or is continued with another :: outside the parentheses. Most symbolic references are done with this notation:

my $foo = "Foo";
my $bar = "Bar";
my $foobar = "Foo::Bar";
$::($bar)              # lexically-scoped $Bar
$::("MY::$bar")        # lexically-scoped $Bar
$::("OUR::$bar")       # package-scoped $Bar
$::("GLOBAL::$bar")    # global $Bar
$::("PROCESS::$bar")   # process $Bar
$::("PARENT::$bar")    # current package's parent's $Bar
$::($foobar)           # $Foo::Bar
@::($foobar)::baz      # @Foo::Bar::baz
@::($foo)::Bar::baz    # @Foo::Bar::baz
@::($foobar)baz        # ILLEGAL at compile time (no operator baz)
@::($foo)::($bar)::baz # @Foo::Bar::baz

An initial :: doesn't imply global; here as part of the interpolation syntax it doesn't even imply package. After the interpolation of the ::() component, the indirect name is looked up exactly as if it had been there in the original source code, with priority given first to leading pseudo-package names, then to names in the lexical scope (searching scopes outwards, ending at CORE). The current package is searched last.

Use the MY pseudopackage to limit the lookup to the current lexical scope, and OUR to limit the scopes to the current package scope.

In the same vein, class and method names can be interpolated too:

role with-method {
        method a-method { return 'in-a-method of ' ~ $?CLASS.^name  };
    }
class a-class does with-method {
        method another-method { return 'in-another-method' };
    }
class b-class does with-method {};
my $what-class = 'a-class';
say ::($what-class).a-method; # OUTPUT: «in-a-method of a-class␤»
    $what-class = 'b-class';
    say ::($what-class).a-method; # OUTPUT: «in-a-method of b-class␤»
my $what-method = 'a-method';
    say a-class."$what-method"(); # OUTPUT: «in-a-method of a-class␤»
    $what-method = 'another-method';
    say a-class."$what-method"(); # OUTPUT: «in-another-method␤»

Direct lookup

To do direct lookup in a package's symbol table without scanning, treat the package name as a hash:

Foo::Bar::{'&baz'}  # same as &Foo::Bar::baz
PROCESS::<$IN>      # same as $*IN
Foo::<::Bar><::Baz> # same as Foo::Bar::Baz

Unlike ::() symbolic references, this does not parse the argument for ::, nor does it initiate a namespace scan from that initial point. In addition, for constant subscripts, it is guaranteed to resolve the symbol at compile time.

You cannot use this kind of direct lookup inside regular expressions, unless you issue a MONKEY-SEE-NO-EVAL pragma. The main intention of this measure is to avoid user input being executed externally.

The null pseudo-package is the same search list as an ordinary name search. That is, the following are all identical in meaning:

$foo
::{'$foo'}
::<$foo>

Each of them scans the lexical scopes outward, and then the current package scope (though the package scope is then disallowed when "strict" is in effect).

Package lookup

Subscript the package object itself as a hash object, the key of which is the variable name, including any sigil. The package object can be derived from a type name by use of the :: postfix:

MyType::<$foo>

Class member lookup

Methods—including auto-generated methods, such as public attributes' accessors—are stored in the class metaobject and can be looked up through by the lookup method.

Str.^lookup('chars')

Globals

Interpreter globals live in the GLOBAL package. The user's program starts in the GLOBAL package, so "our" declarations in the mainline code go into that package by default. Process-wide variables live in the PROCESS package. Most predefined globals such as $*UID and $*PID are actually process globals.

Programmatic use of modules

It is sometimes useful to be able to programmatically define and use modules. Here is a practical example.

Assume we have a series of modules with the module files in a directory tree like this:

lib/
    TomtomMaps/
        Example/
            # a directory of example file modules programmatically
            # created from the Tomtom Maps SDK
            A01.rakumod
            #...
            C09.rakumod
            #...

Module TomtomMaps::Example::C09 looks like this:

unit module TomtomMaps::Example::C09;

# ensure you use the 'our' declarator
our sub print-example($fh, # filehandle open for writing
                      :$api-maps-key
) { # do not need to export the sub
    $fh.print: qq:to/HERE/;
    # ... the example html file
    HERE
}

We can access and use the subroutines like this:

use lib 'lib';
my $module-dir = 'TomtomMaps::Example';
my $example    = 'C09';
my $m          = "{$module-dir}::{$example}";

# you must use the runtime 'require', not the compile-time 'use'
require ::($m);

my $fh = open "./example-{$example}.html", :w;
my $api-maps-key = 'ghghfxnnhrgfsWE.mmn';

# execute the subroutine
&::($m)::print-example($fh, :$api-maps-key); # the map's html file is written

$fh.close;

See Also

Containers

A low-level explanation of Raku containers

Contexts and contextualizers

What are contexts and how to switch into them

Control flow

Statements used to control the flow of execution

Enumeration

An example using the enum type

Exceptions

Using exceptions in Raku

Functions

Functions and functional programming in Raku

Grammars

Parsing and interpreting text

Hashes and maps

Working with associative arrays/dictionaries/hashes

Input/Output the definitive guide

Correctly use Raku IO

Lists, sequences, and arrays

Positional data constructs

Metaobject protocol (MOP)

Introspection and the Raku object system

Native calling interface

Call into dynamic libraries that follow the C calling convention

Raku native types

Using the types the compiler and hardware make available to you

Newline handling in Raku

How the different newline characters are handled, and how to change the behavior

Numerics

Numeric types available in Raku

Object orientation

Object orientation in Raku

Operators

Common Raku infixes, prefixes, postfixes, and more!

Performance

Measuring and improving runtime or compile-time performance

Phasers

Program execution phases and corresponding phaser blocks

Pragmas

Special modules that define certain aspects of the behavior of the code

Quoting constructs

Writing strings and word lists, in Raku

Regexes

Pattern matching against strings

Sets, bags, and mixes

Unordered collections of unique and weighted objects in Raku

Signature literals

A guide to signatures in Raku

Statement prefixes

Prefixes that alter the behavior of a statement or a set of them

Data structures

How Raku deals with data structures and what we can expect from them

Subscripts

Accessing data structure elements by index or key

Syntax

General rules of Raku syntax

System interaction

Working with the underlying operating system and running applications

Date and time functions

Processing date and time in Raku

Traits

Compile-time specification of behavior made easy

Unicode versus ASCII symbols

Unicode symbols and their ASCII equivalents

Unicode

Unicode support in Raku

Variables

Variables in Raku

Independent routines

Routines not defined within any class or role.

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