Joel's Blog

Adventures in Perl 6, part II

Pixelart Camelia

One feature of p6doc was the ability to search for single routines by their name only. This might be useful if we want to know which types harbor a routine of the given name, or whether the routine exists at all.

In the original p6doc, this feature had it’s problems though, it was pretty slow and unable to handle a few edge cases:

$ time p6doc -f say
We have multiple matches for 'say'

	Type::Mu.say Type::Proc::Async.say Type::IO::Handle.say Type::IO::CatHandle.say
	Type::IO.say


real	0m5.317s
user	0m6.854s
sys		0m0.149s
$ p6doc -f exit
No documentation found for a routine named 'exit'

The way it worked was by building an index for routines, methods, subroutines and writing it to a file as a raw Perl 6 data.

After rewriting most of p6doc, routine search can be approached in a slightly different manner.

There are currently ~1700 routines described inside the Perl 6 documentation, so preserving the idea of keeping an index is probably not the worst starting point. However the index is now more simple: it consists of a Hash which has only the routine names as keys, and an Array containing the types it can be found in as values, nothing more. The storage is done in a JSON file.

Let’s take a step back to take a look at what might happen in general when searching for a single routine name. There are 2 basic outcomes:

  1. The routine is found multiple times, associated with different types. This is very likely.
  2. The routine is only found once.

In case 1., all we have to do is show which types the routine is associated with and leave it the user which one to read. In case 2., we can print the documentation for the routine directly.

If we only get a single result, we already have a routine name, and a type, so we can simply hand these two elements over to MAIN and look up the documentation the same way as with a regular type search.

Time to give it a try:

$ time perl6 -Ilib bin/p6doc -d=./doc -r=say

say in:

Mu
routines
Proc::Async
IO::CatHandle
IO::Handle

real	0m0.301s
user	0m0.380s
sys		0m0.099s
$ perl6 -Ilib bin/p6doc -d=./doc -r=exit
  (routines) sub exit

Defined as:

    multi sub exit()
    multi sub exit(Int(Any) $status)

Exits the current process with return code $status or zero if no value has
been specified. The exit value ($status), when different from zero, has to
be opportunely evaluated from the process that catches it (e.g., a shell);
it is the only way to return an exit code different from zero from a Main.

exit prevents the LEAVE phaser to be executed, but it will run the code in
the &*EXIT variable.

exit should be used as last resort only to signal the parent process about
an exit code different from zero, and not to terminate exceptionally a
method or a sub: use exceptions instead.