Perl 6 has this wonderful thing called MAIN
which is a built-in modulino thingy.
In my excellent number hobby (which I started writing about in Mastering Perl even after I switched to C), I’ve been converting some bits to Perl 6 just for giggles. There’s a small Perl 5 module I wrote to get the number of CPUs I rewrote in Perl 6. It’s not sophisticated or surprising. It’s actually quite banal in function; merely dispatch to some method that knows what to do on the platforms I care about. And, be a modulino.
module CpuCount { sub run () is export { say get_cpu_count(); } sub get_cpu_count () is export { state $dispatch = { freebsd => &_freebsd, _default => &_posix, }; my $key = $dispatch.{ $*DISTRO.name }:exists ?? $*DISTRO.name !! '_default'; $dispatch.{ $key }.(); } sub _freebsd () { _get_conf( 'NPROCESSORS_ONLN' ) } sub _posix () { _get_conf( '_NPROCESSORS_ONLN' ) } sub _get_conf ( $key ) { state $command = '/usr/bin/getconf'; unless $key ~~ m/ ^^ <[_A..Z0..9]>+ $$ / { warn "Key $key doesn't look acceptable"; return; }; qq:x{$command $key 2>/dev/null}.chomp; } } sub MAIN { import CpuCount; run; }
First, MAIN
. Perl 6 calls that if the file is the top-level thingy rather than something that’s loaded by something else. No more caller
tricks. It’s even better though. Although I don’t need it here, if I give MAIN
a signature, it does some argument handling automatically. And, lexical imports!
Back to the top of the program, I can create a module
, similar to Perl 5’s package BLOCK
syntax. I really like that. I get export handling without inheritance (that I can see, at least) by marking what is eligible with is export
.
Inside get_cpu_count
, I use the $*DISTRO
special variable to find out what system I’m on. That’s an object with various parts I can access.
In the dispatch table, I get a reference to a subroutine by using the &
in front of it. That messed me up for a bit, but I think I like that.
In _get_conf
, I have a regex. That’s changed quite a bit with double typing. The ^^
and $$
are anchors, whitespace is insignificant by default, and character classes are much fancier. Those are put in <[ ... ]>
because you can do set operations on the things in the square brackets. Very fancy, but there’s more typing. I also have to use ..
to make a range of characters. Disk drives are cheap, so let’s use up those bytes!
I love string objects. I call the external command and can chomp
it right away. And, chomp
returns the modified string like God always wanted.