Some Questions about Perl 6 Modules

Getting back into Perl 6 after being away from it for a while, I realized I’m still not comfortable with how Perl 6 handles packages in general. I’m quite a bit more familiar with C++’s namespaces and stone-age way of handling these things, for the record, so I may be expecting unreasonable things from Perl 6. (It doesn’t help that there’s little documentation on this stuff.)

So I’m making this post to collect all my concerns in one place. I’ll be updating this post as I get answers.

Q#1: How do I split a package across multiple files?

In other words: C++’s handling of namespaces. I want to be able to define a particular package’s contents across a number of files. As an example:

package Foo {
    class Bar { ... }
}
package Foo {
    class Baz { ... }
}

Q#2: How do the different names relate?

As an example, let’s say I have a file that can be used by the name A::B (for simplicity, at A/B.pm6). Here are its contents:

unit module C::D;

class E { ... }

Now I use the module in another script file. Which of the say statements are correct?

use A::B;

say A::B::C::D::E; # 1
say C::D::E;       # 2
say E;             # 3

For bonus points, what happens when the module name in the module file is also A::B? What happens if someone puts names the class C::D::E (thereby replicating the unit name)?

I suppose the question here can also be phrased as “Which of these various names matters where? And when do they need to be combined, and how?”

Q#3: What does a unit declaration mean?

In other words, what’s the difference between

unit module Foo;

class Bar { ... }

and

module Foo {
    class Bar { ... }
}

? What differences are between these two, if any? Would a file with multiple braced module declarations act like multiple unit‘d files? Does this choice affect Q#2?

Q#4: What does leaving out a package name mean?

That is, if I leave out the unit module or package foo { } in a package, how does that affect the symbols declared in the file? Are they in global scope?

Q#5: Where is exporting useful?

Is the is export construct only useful inside modules? How about all packages in general? Does it work inside “package-less” module files (see Q#4)?

Q#6: Does it matter how I declare a “nested” name?

Or, put another way, what’s the difference between

package Foo {
    class Bar { ... }
}

and

class Foo::Bar { ... }

, assuming Foo as a name doesn’t yet exist in either case?

Q#7: What are packages and modules anyway?

What’s the difference between a package and a module, exactly? And are there any other package-like constructs I should know about?

Q#FINAL: How to packages for C++ devs?

Ultimately, my confusion and bewilderment stems from being quite OK with how you handle these kinds of things in C++. And Perl 6’s methods feel to me, at least at the moment, to be way more freeform and liberal, and thus more confusing.

To help out with describing my wants, here’s what I want to do (and what C++ does) in Perl 6:

  1. I want to define at least one namespace filled with all the classes, enums, and so on for my project.
  2. This namespace qualifies its constituent identifiers so people using my project won’t run into name conflicts just by importing it.
  3. This namespace should not depend on the filesystem layout, since I prefer to organize files and their contents by what makes sense from an editing perspective. I don’t like enforced organization for braindead packaging systems (looking at you, Java).
  4. People wanting to use various elements of my project can do so with use statements whose names aren’t inextricably linked to the code imported. In C++, this is where #include <foo/bar.hpp> doesn’t mean all the imported symbols are under a foo/bar.hpp:: namespace.
  5. When people import my project, they get qualified names by default, in other words requiring extra work to unqualify them (e.g. using namespace std; in C++).

In short: I want a C++ style way of developing modules and other such projects, since that’s what I’m familiar with :P .

But even if Perl 6 can’t be (easily) made to work this way, I still want to know how it actually does work. Because it’s not at all easy to tell with the present state of documentation. I hope that as my questions get answers, this can be part of the improvement to documentation.

Advertisements