For a complete explanation of modules, please refer to the Perl 6 documentation This tutorial is a short and sweet explanation of modules, and this one is a bit more in depth, so pick your poison :).

In brief summary, a module is a set of files in a namespace. So for example, if there was a module named Foo that contained the function bar(), I could use it from inside my program by first importing the module by writing "use Foo;" and then calling the function by writing "Foo::bar()".

There are three different keywords that you can use to indicate you want to import a file:andFor my purposes, the distinctions between these three haven't been super significant, as all three indicate that a module is needed. If you would like to get clarification on the minor differences between then and how you should use them in your code, please refer to the docs . Additionally, if you'd like an explanation of how to make a module, tbrowder and ttjjss both have good posts on this topic.

How do we know a module needs to be loaded?

When you hand a program to perl6, it runs through a number of steps before eventually compiling and running the program. This section goes over how it gets to the point of parsing the program, and some significant steps after the program is evaluated.





perl6 does. I've included them here for ease of reading. Please note that this is a bit of a simplification of how module loading happens, as there are a lot of steps along the way that have to do with exactly how the compiler parses the user input, which is a bit above my pay grade :) The first five steps of this section may look familiar! That is because they are the same as the first five steps in this blog post on what runningdoes. I've included them here for ease of reading. Please note that this is a bit of a simplification of how module loading happens, as there are a lot of steps along the way that have to do with exactly how the compiler parses the user input, which is a bit above my pay grade :)

At this point, we are fully in the land of compilers. The program will be parsed, piece by piece, and the keywords use, require, and need will identify that the token following those words is the name of a module that needs to be loaded. I'm not going to go into depth on how the compiler works, as that is outside the scope of this blog, but if you'd like to learn more, here are a couple of resources:

The Rakudo and NQP Internals course is a very useful resource developed by jnthn which goes over the outlines of how the Rakudo Perl 6 compiler works

Let's Build a Compiler is a useful book that goes over in general how compilers work, and several different techniques on making them.

Jnthn's blog in general is very interesting and informative when trying to get an understanding of the bigger picture of Rakudo. One of the posts I found interesting is one of the early roadmap posts from 2010. Obviously, it's a bit out of date, but still very informative and interesting. * These are added to the list of stages during set-up, and may be slightly different from the stages that occur on your machine depending on your configuration of perl6. Then what?





I uncovered a lot of this trail through tracking down perl6 to look for the modules in a temp directory:









As always, if you see an inaccuracy or a misunderstanding on my part, please let me know!



So, thanks to the wonderful magic that happened during compilation, we now know that we need to load some modules. What happens now? So, now we're at the point where everything has been parsed and processed and we know that a module needs to be loaded. What happens from there?I uncovered a lot of this trail through tracking down a bug mentioned by vrurg and Xliff and by hitting error messages like this while I was trying to getto look for the modules in a temp directory:As always, if you see an inaccuracy or a misunderstanding on my part, please let me know!So, thanks to the wonderful magic that happened during compilation, we now know that we need to load some modules. What happens now?

dissect_bytecode to find At this point, it is possible to continue chasing down the rabbit hole from MVM_load_bytecode to MVM_cu_map_from_file to MVM_cu_from_bytes to MVM_bytecode_unpack toto find some more of the errors I encountered along the way, but for the vast majority of people, I don't think that's a rabbit hole worth devoting mental energy to, so I'm going to stop here. Please feel free to follow the links and read the code that connects these bits if you're tracking down an error that looks something like this:





Why does this matter?

Now that most of the path of how module loading works is identified, it's much easier to find the information for which modules are needed, rather than relying on having a file that contains the output generated by calling perl6 --target=mbc --output=foo.moarvm foo.pl6. So that's one victory! Simplifying the process of calling perl6 --compile as much as possible is definitely a goal.





It also gives us a better idea of how to get perl6 to use the modules packaged up in the executable generated by perl6 --compile=foo foo.pl6. We have two options at this point, we can either insert the expected files to where perl6 would expect them to be, or we can figure out how to redirect perl6 to look somewhere else for them. As I briefly mentioned earlier, I've spent a lot of time in the past month trying to accomplish the second option with little to no success (causing me to encounter a lot of the errors that helped me track down what was happening).



