Skip to content

Commit

Permalink
Indexes import where it's effectively explained
Browse files Browse the repository at this point in the history
Closes #2304

Also some reflow, linking and reformatting.
  • Loading branch information
JJ committed Sep 10, 2018
1 parent 766353e commit 1444d13
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 47 deletions.
24 changes: 11 additions & 13 deletions doc/Language/module-packages.pod6
Expand Up @@ -8,13 +8,12 @@
I<N.B.> "Module" is an overloaded term in Perl 6; this document
focuses on use of the C<module> declarator.
=head1 What are modules?
Modules, like classes and grammars, are a kind of
L<package|/language/packages>. Module objects are instances of the
C<ModuleHOW> metaclass; this provides certain capabilities useful
for creating namespaces, versioning, delegation and data encapsulation (see
C<ModuleHOW> metaclass; this provides certain capabilities useful for
creating namespaces, versioning, delegation and data encapsulation (see
also L<class|/syntax/class> and L<role|/syntax/role>).
To create a module, use the C<module> declarator:
Expand All @@ -37,7 +36,7 @@ caller's namespace once the module has been imported with C<import>
or C<use>. A module can also selectively expose symbols within its
namespace for qualified reference via C<our>.
X<|import>
=head2 Working with modules
To illustrate module scoping and export rules, let's begin by
Expand All @@ -49,15 +48,14 @@ defining a simple module C<M>:
sub friendly-greeting is export { greeting('friend') }
}
Recall that subroutines are lexically scoped unless otherwise
specified (declarator L<C<sub>|/syntax/sub>
is equivalent to C<my sub>), so C<greeting> in the above example
is lexically scoped to the module and inaccessible outside of it.
We've also defined C<loud-greeting> with the C<our> declarator,
which means that in addition to being lexically scoped it is aliased
in the module's symbol table. Finally, C<friendly-greeting> is
marked for export; it will be registered in the I<caller's> symbol
table when the module is imported:
Recall that subroutines are lexically scoped unless otherwise specified
(declarator L<C<sub>|/syntax/sub> is equivalent to C<my sub>), so
C<greeting> in the above example is lexically scoped to the module and
inaccessible outside of it. We've also defined C<loud-greeting> with the
C<our> declarator, which means that in addition to being lexically
scoped it is aliased in the module's symbol table. Finally,
C<friendly-greeting> is marked for export; it will be registered in the
I<caller's> symbol table when the module is imported:
=begin code :skip-test<&friendly-greeting already exported>
import M; # import the module
Expand Down
76 changes: 42 additions & 34 deletions doc/Language/modules.pod6
Expand Up @@ -94,7 +94,8 @@ L<need|/language/modules#need> MyModule;
import MyModule;
=end code
See also L<Selective Importing|/language/modules#Exporting_and_selective_importing> to restrict what you import.
See also L<Selective Importing|/language/modules#Exporting_and_selective_importing>
to restrict what you import.
=head3 C<require>X<|require>
Expand All @@ -109,19 +110,22 @@ indirect lookup.
my $name = 'MyModule';
require ::($name);
The symbols provided by the loaded module will not be imported into the current
scope. You may use L<dynamic lookup|/language/packages#index-entry-::()> or
L<dynamic subsets|/language/typesystem#subset> to use them by providing the
fully qualified name of a symbol, for instance:
The symbols provided by the loaded module will not be imported into the
current scope. You may use
L<dynamic lookup|/language/packages#index-entry-::()> or
L<dynamic subsets|/language/typesystem#subset> to use them by providing
the fully qualified name of a symbol, for instance:
require ::("Test");
my &mmk = ::("Test::EXPORT::DEFAULT::&ok");
mmk('oi‽'); # OUTPUT: «ok 1 - ␤»
The FQN of C<ok> is C<Test::EXPORT::DEFAULT::&ok>. We are aliasing it to C<mmk> so that we can use that symbol provided by C<Test> in the current scope.
The FQN of C<ok> is C<Test::EXPORT::DEFAULT::&ok>. We are aliasing it to
C<mmk> so that we can use that symbol provided by C<Test> in the current
scope.
To import symbols you must define them at compile time. B<NOTE:> C<require>
is lexically scoped:
To import symbols you must define them at compile time. B<NOTE:>
C<require> is lexically scoped:
sub do-something {
require MyModule <&something>;
Expand All @@ -134,10 +138,11 @@ is lexically scoped:
If C<MyModule> doesn't export C<&something> then C<require> will fail.
A C<require> with compile-time symbol will install a placeholder C<package>
that will be updated to the loaded module, class, or package. Note that the
placeholder will be kept, B<even if require failed to load the module.>
This means that checking if a module loaded like this is wrong:
A C<require> with compile-time symbol will install a placeholder
C<package> that will be updated to the loaded module, class, or package.
Note that the placeholder will be kept, B<even if require failed to load
the module.> This means that checking if a module loaded like this is
wrong:
# *** WRONG: ***
try require Foo;
Expand All @@ -159,17 +164,17 @@ a C<Failure>. The correct way is:
=head2 Lexical module loading
Perl 6 takes great care to avoid global state, i.e. whatever you do in your
module, it should not affect other code. That's why e.g. subroutine definitions
are lexically (C<my>) scoped by default. If you want others to see them, you
need to explicitly make them our scoped or export them.
Perl 6 takes great care to avoid global state, i.e. whatever you do in
your module, it should not affect other code. That's why e.g. subroutine
definitions are lexically (C<my>) scoped by default. If you want others
to see them, you need to explicitly make them our scoped or export them.
Classes are exported by default on the assumption that loading a module will not
be of much use when you cannot access the classes it contains. This works as
advertised with a small but important caveat: those classes are not only visible
in the computation unit that loads the module, but globally. This means that as
soon as some code loads a module, those classes are immediately visible
everywhere.
Classes are exported by default on the assumption that loading a module
will not be of much use when you cannot access the classes it contains.
This works as advertised with a small but important caveat: those
classes are not only visible in the computation unit that loads the
module, but globally. This means that as soon as some code loads a
module, those classes are immediately visible everywhere.
For example, given a module C<Foo>:
Expand All @@ -184,10 +189,10 @@ use Foo;
my $foo = Foo.new; # works as expected
my $bar = Bar.new; # huh!? Where is Bar coming from?
This doesn't sound so bad (it at least saves you some typing), except for that
it makes another feature of Perl 6 impossible to have: the ability to load
multiple versions of a module at the same time in different parts of your
program:
This doesn't sound so bad (it at least saves you some typing), except
for that it makes another feature of Perl 6 impossible to have: the
ability to load multiple versions of a module at the same time in
different parts of your program:
=for code :skip-test
{
Expand Down Expand Up @@ -269,15 +274,18 @@ tags: C<ALL>, C<DEFAULT> and C<MANDATORY>.
use MyModule :ALL; # bag, pants, sunglasses, torch, underpants
=end code
Note there currently is no way for the user to import a single object if
the module author hasn't made provision for that, and it is not an easy
task at the moment (see RT #127305). One way the author can provide
such access is to give each C<export> trait its own unique tag. (And the tag
can be the object name!) Then the user can either (1) import all objects:
B<Note>: there currently is no way for the user to import a single
object if the module author hasn't made provision for that, and it is
not an easy task at the moment (see
L<RT #127305|https://rt.perl.org/Public/Bug/Display.html?id=127305>).
One way
the author can provide such access is to give each C<export> trait its
own unique tag. (And the tag can be the object name!) Then the user can
either (1) import all objects:
=begin code :skip-test
use Foo :ALL;
=end code
=begin code :skip-test
use Foo :ALL;
=end code
or (2) import one or more objects selectively:
Expand Down

0 comments on commit 1444d13

Please sign in to comment.