NAME

Synopsis_11 - Modules

AUTHOR

Larry Wall <larry@wall.org>

VERSION

Maintainer: Larry Wall <larry@wall.org>
Date: 27 Oct 2004
Last Modified: 6 Aug 2007
Number: 11
Version: 20

Overview

This synopsis discusses those portions of Apocalypse 12 that ought to have been in Apocalypse 11.

Modules

As in Perl 5, a module is just a kind of package. Unlike in Perl 5, modules and classes are declared with separate keywords, but they're still just packages with extra behaviors.

A module is declared with the module keyword. There are two basic declaration syntaxes:

module Foo; # rest of scope is in module Foo
...

module Bar {...}    # block is in module Bar

The first form is allowed only as the first statement in the file.

A named module declaration can occur as part of an expression, just like named subroutine declarations.

Since there are no barewords in Perl 6, module names must be predeclared, or use the sigil-like ::ModuleName syntax. The :: prefix does not imply top-levelness as it does in Perl 5. (Use ::* or GLOBAL:: for that.)

A bare (unscoped) module declarator declares a nested our module name within the current package. However, at the start of the file, the current package is *, so the first such declaration in the file is automatically global.

You can use our module to explicitly declare a module in the current package (or module, or class). To declare a lexically scoped module, use my module. Module names are always searched for from innermost scopes to outermost. As with an initial ::, the presence of a :: within the name does not imply globalness (unlike in Perl 5).

The ::* namespace is not "main". The default namespace for the main program is ::*Main, which it switches to from * as soon as it sees the first declaration, if that declaration doesn't set the package name. (Putting module Main; at the top of your program is redundant, except insofar as it tells Perl that the code is Perl 6 code and not Perl 5 code. But it's better to say "use v6" for that.)

But note that if you say

use v6;
module Foo {...}

you've just created Main::Foo, not *Foo.

Module traits are set using is:

module Foo is bar {...}

Exportation

Exportation is now done by trait declaration on the exportable item:

module Foo;                                # Tagset...
sub foo is export(:DEFAULT)         {...}  #  :DEFAULT, :ALL
sub bar is export(:DEFAULT :others) {...}  #  :DEFAULT, :ALL, :others
sub baz is export(:MANDATORY)       {...}  #  (always exported)
sub bop is export                   {...}  #  :ALL
sub qux is export(:others)          {...}  #  :ALL, :others

Declarations marked as is export are bound into the EXPORT inner modules, with their tagsets as inner module names within it. For example, the sub bar above will bind as &Foo::EXPORT::DEFAULT::bar, &Foo::EXPORT::ALL::bar, and &Foo::EXPORT::others::bar.

Tagset names consisting entirely of capitals are reserved for Perl.

Inner modules automatically add their export list to modules in all their outer scopes:

module Foo {
    sub foo is export {...}
    module Bar {
        sub bar is export {...}
        module Baz {
            sub baz is export {...}
        }
    }
}

The Foo module will export &foo, &bar and &baz by default; calling Foo::Bar.EXPORTALL will export &bar and &baz at runtime to the caller's package.

Dynamic exportation

The default EXPORTALL handles symbol exports by removing recognized export items and tagsets from the argument list, then calls the EXPORT subroutine in that module (if there is one), passing in the remaining arguments.

If the exporting module is actually a class, EXPORTALL will invoke its EXPORT method with the class itself as the invocant.

Compile-time Importation

Importing via use binds into the current lexical scope by default (rather than the current package, as in Perl 5).

use Sense <common @horse>;

You can be explicit about the desired namespace:

use Sense :MY<common> :OUR<@horse> :GLOBAL<$warming>;

That's pretty much equivalent to:

use Sense;
my &common ::= &Sense::common;
our @horse ::= @Sense::horse;
$*warming  ::= $Sense::warming;

It is also possible to re-export the imported symbols:

use Sense :EXPORT;                  # import and re-export the defaults
use Sense <common> :EXPORT;         # import "common" and re-export it
use Sense <common> :EXPORT<@horse>; # import "common" but export "@horse"

In the absence of a specific scoping specified by the caller, the module may also specify a different scoping default by use of :MY or :OUR tags as arguments to is export. (Of course, mixing incompatible scoping in different scopes is likely to lead to confusion.)

Runtime Importation

Importing via require also installs names into the current lexical scope by default, but delays the actual binding till runtime:

require Sense <common @horse>;
require "/home/non/Sense.pm" <common @horse>;

Only explicitly mentioned names may be so installed. In order to protect the run-time sanctity of the lexical pad, it may not be modified by require. Tagsets are assumed to be unknown at compile time, hence tagsets are not allowed in the default import list to :MY, but you can explicitly request to put names into the :OUR scope, since that is modifiable at run time:

require Sense <:ALL>    # does not work
require Sense :MY<ALL>  # this doesn't work either
require Sense :OUR<ALL> # but this works

If the import list is omitted, then nothing is imported. Since you may not modify the lexical pad, calling an importation routine at runtime cannot import into the lexical scope, and defaults to importation to the package scope instead:

require Sense;
Sense.EXPORTALL;   # goes to the OUR scope by default, not MY

(Such a routine may rebind existing lexicals, however.)

Importing from a pseudo-package

You may also import symbols from the various pseudo-packages listed in S02. They behave as if all their symbols are in the :ALL export list:

use GLOBAL <$IN $OUT $ERR>;
require CALLER <$x $y>;

# Same as:
#     my ($IN, $OUT, $ERR) ::= ($*IN, $*OUT, $*ERR)
#     my ($x, $y) := ($CALLER::x, $CALLER::y)

As pseudo-packages are always already preloaded, use and require will never attempt to load, for example, GLOBAL.pm from an external source.

Versioning

When at the top of a file you say something like

module Cat;

or

class Dog;

you're really only giving one part of the name of the module. The full name of the module or class includes other metadata, in particular, the version, and the author.

Modules posted to CPAN or entered into any standard Perl 6 library are required to declare their full name so that installations can know where to keep them, such that multiple versions by different authors can coexist, all of them available to any installed version of Perl. (When we say "modules" here we don't mean only modules declared with the module declarator, but also classes, roles, grammars, etc.)

Such modules are also required to specify exactly which version (or versions) of Perl they are expecting to run under, so that future versions of Perl can emulate older versions of Perl (or give a cogent explanation of why they cannot). This will allow the language to evolve without breaking existing widely used modules. (Perl 5 library policy is notably lacking here; it would induce massive breakage even to change Perl 5 to make strictness the default.) If a CPAN module breaks because it declares that it supports future versions of Perl when it doesn't, then it must be construed to be the module's fault, not Perl's. If Perl evolves in a way that does not support emulation of an older version (at least, back to 6.0.0), then it's Perl's fault (unless the change is required for security, in which case it's the fault of the insensitive clod who broke security :).

The internal API for package names is always case-sensitive, even if the library system is hosted on a system that is not case-sensitive. This implies either some sort of name mangling capability or storage of intermediate products into a database of some sort. In any event, the actual storage location must be encapsulated in the library system such that it is hidden from all language level naming constructs. (Provision must be made for interrogating the library system for the actual location of a module, of course, but this falls into the category of introspection.) Note also that distributions need to be distributed in a way that they can be installed on case-insensitive systems without loss of information. That's fine, but the language-level abstraction must not leak details of this mechanism without the user asking for the details to be leaked.

The syntax of a versioned module or class declaration has multiple parts in which the non-identifier parts are specified in adverbial pair notation without intervening spaces. Internally these are stored in a canonical string form which you should ignore. You may write the various parts in any order, except that the bare identifer must come first. The required parts for library insertion are the short name of the class/module, its version number, and a URI identifying the author (or authorizing authority, so we call it "auth" to be intentionally ambiguous). For example:

class Dog:ver<1.2.1>:auth<cpan:JRANDOM>;
class Dog:ver<1.2.1>:auth<http://www.some.com/~jrandom>;
class Dog:ver<1.2.1>:auth<mailto:jrandom@some.com>;

Since these are somewhat unweildy to look at, we allow a shorthand in which a bare subscripty adverb interprets its elements according to their form:

class Dog:<1.2.1 cpan:JRANDOM>

The pieces are interpreted as follows:

  • Anything matching [<ident> '::']* <ident> is treated as a package name

  • Anything matching v? [\d+ '.']* \d+ is treated as a version number

  • Anything matching <alpha>+ \: \S+ is treated as an author(ity)

These declarations automatically alias the full name of the class (or module) to the short name. So for the rest of the lexical scope, Dog refers to the longer name. The real library name can be specified separately as another adverb, in which case the identifier indicates only the alias within the current lexical scope:

class Pooch:name<Dog>:ver<1.2.1>:auth<cpan:JRANDOM>

or

class Pooch:<Dog 1.2.1 cpan:JRANDOM>

for short.

Here the real name of the module starts Dog, but we refer to it as Pooch for the rest of this file. Aliasing is handy if you need to interface to more than one module named Dog

If there are extra classes or modules or packages declared within the same file, they implicitly have a long name including the file's version and author, but you needn't declare them again.

Since these long names are the actual names of the classes as far as the library system is concerned, when you say:

use Dog;

you're really wildcarding the unspecified bits:

use Dog:ver(Any):auth(Any);

And when you say:

use Dog:<1.2.1>;

you're really asking for:

use Dog:ver<1.2.1>:auth(Any);

Saying 1.2.1 specifies an exact match on that part of the version number, not a minimum match. To match more than one version, put a range operator as a selector in parens:

use Dog:ver(1.2.1..1.2.3);
use Dog:ver(1.2.1..^1.3);
use Dog:ver(1.2.1..*);

When specifying the version of your own module, 1.2 is equivalent to 1.2.0, 1.2.0.0, and so on. However use searches for modules matching a version prefix, so the subversions are wildcarded, and in this context :ver<1.2> really means :ver<1.2.*>. If you say:

use v6;

which is short for:

use Perl:ver<6.*>;

you're asking for any version of Perl 6. You need to say something like

use Perl:<6.0>;
use Perl:<6.0.0>;
use Perl:<6.2.7.1>;

if you want to lock in a particular set of semantics at some greater degree of specificity. And if some large company ever forks Perl, you can say something like:

use Perl:auth<cpan:TPF>

to guarantee that you get the unembraced Perl. :-)

To allow a version specification that works with both Perl 5 and Perl 6, we use variants of the "v6" pseudomodule. This form specifically allows use of a subsequent hyphenated identifier. Before the full specification of Perl 6.0.0 is released, you can use alpha to denote a program using syntax that is still subject to change:

use v6-alpha;

Later on

use v6-std;

will indicate standard version 6 of Perl.

The use v6-alpha line also serves as the Perl 5 incantation to switch to Perl 6 parsing. In Perl 5 this actually ends up calling the v6.pm module with a -alpha argument, for insane-but-useful reasons.

For wildcards any valid smartmatch selector works:

use Dog:ver(1.2.1 | 1.3.4):auth(/:i jrandom/);
use Dog:ver(Any):auth({ .substr(0,5) eq 'cpan:'})

In any event, however you select the module, its full name is automatically aliased to the short name for the rest of your lexical scope. So you can just say

my Dog $spot .= new("woof");

and it knows (even if you don't) that you mean

my Dog:<1.3.4 cpan:JRANDOM> $spot .= new("woof");

The use statement allows an external language to be specified in addition to (or instead of) an authority, so that you can use modules from other languages. The from adverb also parses any additional parts as short-form arguments. For instance:

use Whiteness:from<perl5>:name<Acme::Bleach>:ver<1.12>:auth<cpan:DCONWAY>;
use Whiteness:from<perl5 Acme::Bleach 1.12 cpan:DCONWAY>;  # same thing

The string form of a version recognizes the * wildcard in place of any position. It also recognizes a trailing +, so

:ver<6.2.3+>

is short for

:ver(v6.2.3 .. v6.2.*)

And saying

:ver<6.2.0+>

specifically rules out any prereleases.

If two different modules in your program require two different versions of the same module, Perl will simply load both versions at the same time. For modules that do not manage exclusive resources, the only penalty for this is memory, and the disk space in the library to hold both the old and new versions. For modules that do manage an exclusive resource, such as a database handle, there are two approaches short of requiring the user to upgrade. The first is simply to refactor the module into a stable supplier of the exclusive resource that doesn't change version often, and then the outer wrappers of that resource can both be loaded and use the same supplier of the resource.

The other approach is for the module to keep the management of its exclusive resource, but offer to emulate older versions of the API. Then if there is a conflict over which version to use, the new one is used by both users, but each gets a view that is consistent with the version it thinks it is using. Of course, this depends crucially on how well the new version actually emulates the old version.

To declare that a module emulates an older version, declare it like this:

class Dog:<1.2.1 cpan:JRANDOM> emulates :<1.2.0>;

Or to simply exclude use of the older module and (presumably) force the user to upgrade:

class Dog:<1.2.1 cpan:JRANDOM> excludes :<1.2.0>;

The name is parsed like a use wildcard, and you can have more than one, so you can say things like:

class Dog:<1.2.1 cpan:JRANDOM>
    emulates Dog:auth(DCONWAY|JCONWAY|TCONWAY):ver<1.0+>
    excludes Fox:<3.14159 http://oreillymedia.com>
    emulates Wolf:from<C# 0.8..^1.0>;

Forcing Perl 6

To get Perl 6 parsing rather than the default Perl 5 parsing, we said you could force Perl 6 mode in your main program with:

use v6-alpha;

Actually, if you're running a parser that is aware of Perl 6, you can just start your main program with any of:

use v6;
module;
class;

Those all specify the latest Perl 6 semantics, and are equivalent to

use Perl:ver(v6..*):auth(Any);

To lock the semantics to 6.0.0, say one of:

use Perl:ver<6.0.0>;
use :<6.0.0>;
use v6.0.0;

In any of those cases, strictures and warnings are the default in your main program. But if you start your program with a bare version number or other literal:

v6.0.0;
v6;
6;
"Coolness, dude!";

it runs Perl 6 in "lax" mode, without strictures or warnings, since obviously a bare literal in a void context ought to have produced a warning. (Invoking perl with -e6 has the same effect.)

In the other direction, to inline Perl 5 code inside a Perl 6 program, put use v5 at the beginning of a lexical block. Such blocks can nest arbitrarily deeply to switch between Perl versions:

use v6-std;
# ...some Perl 6 code...
{
    use v5;
    # ...some Perl 5 code...
    {
        use v6-std;
        # ...more Perl 6 code...
    }
}

It's not necessary to force Perl 6 if the interpreter or command specified already implies it, such as use of a "#!/usr/bin/perl6" shebang line. Nor is it necessary to force Perl 6 in any file that begins with the "class" or "module" keywords.