Day 12: Modules and Exporting

Today I’d like to talk about a fairly fundamental subject: libraries.

To write a library in Perl 6, we use the “module” keyword:

module Fancy::Utilities {
    sub lolgreet($who) {
        say "O HAI " ~ uc $who;
    }
}

Put that in Fancy/Utilities.pm somewhere in $PERL6LIB and we can use it like the following:

use Fancy::Utilities;
Fancy::Utilities::lolgreet('Tene');

That’s hardly ideal.  Just like in Perl 5, we can indicate that some symbols from the module should be made available in the lexical scope of the code loading the module.  We’ve got a rather different syntax for it, though:

# Utilities.pm
module Fancy::Utilities {
  sub lolgreet($who) is export {
    say "O HAI " ~ uc $who;
  }
}

# foo.pl
use Fancy::Utilities;
lolgreet('Jnthn');

If you don’t specify further, symbols marked “is export” are exported by default.  We can also choose to label symbols as being exported as part of a different named group:

module Fancy::Utilities {
 sub lolgreet($who) is export(:lolcat, :greet) {
  say "O HAI " ~ uc $who;
 }
 sub nicegreet($who) is export(:greet, :DEFAULT) {
  say "Good morning, $who!"; # Always morning?
 }
 sub shortgreet is export(:greet) {
  say "Hi!";
 }
 sub lolrequest($item) is export(:lolcat) {
  say "I CAN HAZ A {uc $item}?";
 }
}

Those tags can be referenced in the code loading this module to choose which symbols to import:

use Fancy::Utilities; # Just get the DEFAULTs
use Fancy::Utilities :greet, :lolcat;
use Fancy::Utilities :ALL; # Everything marked is export

Multi subs are export by default, so you only need to label them if you want to change that.

multi sub greet(Str $who) { say "Good morning, $who!" }
multi sub greet() { say "Hi!" }
multi sub greet(Lolcat $who) { say "O HAI " ~ $who.name }

Classes are just a specialization of modules, so you can export things from them as well.  In addition, you can export a method to make it available as a multi sub.  For example, the setting exports the “close” method from the IO class so you can call “close($fh);”

class IO {
    ...
    method close() is export {
        ...
    }
    ...
}

Perl 6 does support importing symbols by name from a library, but Rakudo does not yet implement it.