https://martimm.github.io/gnome-gtk3/content-docs/tutorial/Application/sceleton.html , abbreviated:
In Raku, it is important that the main program is kept small. This is because all code, program and modules are parsed and compiled into an intermediate code which will be executed by a virtual machine. Most of the time that will be MoarVM but there is also a JVM and later possibly others. Anyways, before running, the compiled modules are saved into .precomp directories but not the program. This means that the program always get parsed and compiled before running and that is the reason to keep it small.
use UserAppClass; my UserAppClass $user-app .= new; exit($user-app.run);
Well, you can’t get smaller than this …, or maybe use this one-liner;
exit(UserAppClass.new.run)
.The rest of the code is defined in the UserAppClass.
Very good.
Now, our program needs to accept arguments. sub MAIN
does parsing arguments and generating $*USAGE
gratis, so we would utilize sub MAIN
.
We put sub MAIN
into a use
d by .raku
program .rakumod
but we get the .raku
program ignorant of the arguments. And sub MAIN
is not executed when in a module.
We put sub MAIN
into the .raku
program so that it understands arguments but it is no longer small.
Furthermore, embedded POD
for the program is probably expected to reside in the .raku
program.
Put POD
into a use
d by .raku
program .rakumod
and we get the POD
somewhat hidden.
Put POD
into the .raku
program and again it is no longer small.
Also, are there any naming conventions for such an approach?
Say, you have a program Report when your coffee is ready
. Its sub MAIN
is in coffee-ready.raku
, and you use
a QueryCoffeeMachine.rakumod
.
You change the layout of your files and now for the same program Report when your coffee is ready
you have a coffee-ready.raku
launcher, a coffee-ready.MAIN.rakumod
with sub MAIN
's functionality in it and a QueryCoffeeMachine.rakumod
.
I believe QueryCoffeeMachine.rakumod
stays intact,
I feel coffee-ready.raku
should also keep the name despite changing its contents
but how should coffee-ready.MAIN.rakumod
be named?
Anyways, before running, the compiled modules are saved into
.precomp
directories but not the program.
Aiui someone could extend precompilation to the main program file, but it's a low priority for core devs given that one can work around it with solutions like the following:
- ...
sub MAIN
is not executed when in a module.
If you export/import it into the main program, the module's MAIN
will execute when you run the main program:
# MAIN.rakumod
our sub MAIN (Int $int-arg, Str $str-arg) { $int-arg }
# main.raku
use lib '.';
use MAIN;
- ... we get the
.raku
program ignorant of the arguments
If you wrap
the imported MAIN
in the main program, you will know the arguments:
# main.raku
use lib '.';
use MAIN;
&MAIN.wrap: -> |args { say args; callsame }
(If the args passed at the CLI don't match the signature of the MAIN
sub imported from the MAIN
module, then the usage message is displayed. Otherwise the wrapper in main.raku
gets called and can do what it wishes with the passed args, and decide how it will call the imported MAIN
.)
(I lifted this solution from Can I capture the returned value of a routine used in RUN-MAIN?.)
- Put POD into a ...
.rakumod
and we get the POD somewhat hidden.
I don't know of an existing way to avoid that. (Perhaps checkout Access POD from another Raku file for how to at least get access to POD in another file.)
Perhaps a new question narrowly focused on just that aspect is in order?
- how should
.MAIN.rakumod
be named?
If it were me, off the top of my head, I might have a Coffee-Ready
folder, and then within that, a coffee-ready.raku
, a MAIN.rakumod
, and a QueryCoffeeMachine.rakumod
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With