<!-- @page { margin: 2cm } P { margin-bottom: 0.21cm } -->
Module loading in Perl 6 is considerably different than in Perl 5. The biggest difference is that in Perl 5, you're always in the main namespace and that is global, which means that it doesn't matter what gets some module loaded, if it ends up in main, you'll be able to find it. Like:
# in some random file loaded indirectly...
*{'main::Foo::Bar::new'} = sub {
return bless {}, 'Foo::Bar';
}
# in your source file
my $a = Foo::Bar->new();
In Perl 6 that is not the case, when you ask for Foo::Bar, it will do a lexical lookup for the package Foo, which means that it won't immediatly look for it in the global namespace. Although all files start parsing in the GLOBAL package, and by default a class is our, which means that
use v6;
# in some random file loaded indirectly
class Foo::Bar {
...
}
# in your source file
my $a = GLOBAL::Foo::bar.new(); # this will work
my $b = Foo::Bar.new(); # this won't
That means that, unlike Perl 5 require, module loading in Perl 6 is not just about loading a file, but it also needs to install a symbol in your lexical scope pointing to the loaded module. And to do that Perl 6 has four control statements: “need”, “use”, “require” and “defines”.
-
“need” simply loads something at compile-time without doing any import;
-
“require” is the run-time version of “need”;
-
“defines” explicitly tells to import some module's exports;
-
“use” is a shortcut to “need X defines *”
But that goes a bit beyond that. Consider the following source file, named Sense.pm:
class Sense {
...
}
class Nonsense {
...
}
When that module is loaded, the two classes are loaded into the comp_unit scope and aliased in the GLOBAL package (as they are “our”). When you
need Sense;
It will load Sense.pm, but it also need to have a local symbol for the “Sense” name, so somehow the implementation of “need” will, at some point, have access to the comp_unit scope of Sense.pm, in order to find a symbol named “Sense”, and alias it back to the current scope. The practical implication to that is that “Nonsense” is not available as a local symbol, but it also tells us a lot about how the loading process work. Basically:
The module loading requires the code causing the load to have access to the recently-loaded-module's outermost lexical scope!
So, it seems that module loading will require one to cache the relationship between the filename and the outermost lexical scope, so the compilation is re-used when some other code “need”s this module. There are some other subtle issues about module loading that I'm going to adress in other posts, but that's it for now.
Leave a comment