DEV Community

Cover image for Doc Mirages
Elizabeth Mattijsen
Elizabeth Mattijsen

Posted on

Doc Mirages

This is part seven in the "Cases of UPPER" series of blog posts, describing the Raku syntax elements that are completely in UPPERCASE.

This part will discuss the final set of (non-)existing phasers in the Raku Programming Language.

But first: --doc

The --doc command line argument to raku is described as:

--doc         extract documentation and print it as text
--doc=module  use Pod::To::[module] to render inline documentation
Enter fullscreen mode Exit fullscreen mode

So what that basically does, is process the source of the program to be executed as documentation, and render that documentation in various forms.

Internally this is achieved by loading the Pod::To::xxx module (with "xxx" defaulting to "Text" in case of --doc without arguments). It then installs an INIT phaser that basically does:

INIT {
    say Pod::To::xxx.render($=pod);
    exit;
}
Enter fullscreen mode Exit fullscreen mode

Note that the Pod::To::Text module is installed as part of the rakudo distribution (whether it should be considered part of the Raku Programming Language specification is yet unclear).

Other renderers such as Pod::To::HTML, Pod::To::PDF and Pod::To::Markdown would have to be installed first from the ecosystem (e.g. zef install Pod::To::Markdown).

With that under our belt, we can start discussing the DOC phaser.

DOC

There is not one single DOC phaser, there are actually three of them:

  • DOC BEGIN - add BEGIN phaser but only if --doc is set
  • DOC CHECK - add CHECK phaser but only if --doc is set
  • DOC INIT - add INIT phaser but only if --doc is set

Another way of thinking about this, is that the DOC phaser could be thought of as a sort of statement prefix that will add the phaser only if --doc was specified on the command line. In pseudo-code, for DOC BEGIN:

if --doc is set {
    BEGIN ...;
}
Enter fullscreen mode Exit fullscreen mode

Note that if the --doc is not specified, the phasers will not be executed. Observe the difference between:

$ raku -e 'DOC BEGIN say "begin"; DOC CHECK say "check"; DOC INIT say "init"'
Enter fullscreen mode Exit fullscreen mode

not showing anything, while:

$ raku --doc -e 'DOC BEGIN say "begin"; DOC CHECK say "check"; DOC INIT say "init"'
begin
check
init
Enter fullscreen mode Exit fullscreen mode

will execute the phasers and shows the output.

There's only one "but": even though the DOC phasers are only added if --doc is specified, they must contain valid Raku code to prevent errors:

$ raku -e 'DOC BEGIN +-+'            
===SORRY!=== Error while compiling -e
Prefix + requires an argument, but no valid term found.
Did you mean + to be an opening bracket for a declarator block?
at -e:1
Enter fullscreen mode Exit fullscreen mode

So what use are they? Looking at the ecosystem, there actually only appears to be one type of use that makes sense. And that is functionality offered by the POD::EOD module, which places declarator documentation at the end of the documentation, rather than where they occur in the source code. Which works because it directly modifies the content of the $=pod variable.

Yours truly has not been able to find any other (correct) usage.

TEMP

The TEMP phaser is a bit of a mirage. In the old design documents it was mentioned in S06 - Temporization.

However it looks like sometime in May 2012 let and temp were implemented. But the described TEMP phaser never was implemented in all of the years since then. Probably because the functionality of temp and let covered almost all use cases, combined with the KEEP and UNDO phasers, so nobody felt the need to actually implement support for it.

Oddly enough the syntax for the TEMP phaser does exist.

$ raku -e 'TEMP say "temp"; say "alive";
alive
Enter fullscreen mode Exit fullscreen mode

But it just doesn't do anything. And after this blog post, chances are that the support for the syntax will be removed (see problem solving issue).

COMPOSE

The COMPOSE phaser is even more of a mirage, as it is not even partly implemented. Its only mention is in the S04 - Phasers section of the old design documentation.

However developers wanting to use roles when composing another role or class often refer to the lack of its existence.

The thing is that most of the functionality of the mythical COMPOSE phaser is already available: any code that exists in the mainline of a role, will be executed every time the role is consumed by a class at compile time. A small contrived example:

role A {
    say "composing $?CLASS.^name()";
}
class B does A { }
class C does A { }
BEGIN say "begin";
Enter fullscreen mode Exit fullscreen mode

will show:

composing B
composing C
begin
Enter fullscreen mode Exit fullscreen mode

Note that the $?CLASS compile time variable contains the type object of the class being composed. And in August 2020 it basically became clear that a COMPOSE phaser would not be needed. Well, at least not until someone can show that a COMPOSE phaser offers more functionality than the current way of executing the mainline of the role is offering.

Conclusion

The DOC set of phasers is activated with the --doc command line argument: without that having been specified, all DOC phasers are no-ops but need to be syntactically correct. Their use appears to be limited.

The TEMP phaser was never implemented, but the temp and let prefix operators, as well as the KEEP and UNDO phasers, provide the functionality promised by TEMP phaser.

The COMPOSE phaser was never implemented, because the mainline of a role is executed when a role is consumed in a class, effectively providing exactly the functionality promised by that phaser. At least so far.

This concludes the seventh episode of cases of UPPER language elements in the Raku Programming Language. This also concludes all phasers in Raku. Next up will describe the uppercase methods that you, as a user of the Raku Programming Language, can provide in your code to tweak behaviour. Stay tuned!

Top comments (0)