Thu, 12 Apr 2012

Rakudo Hack: Dynamic Export Lists

Rakudo's meta programming capabilities are very good when it comes to
objects, classes and methods. But sometimes people want to generate
subroutines on the fly and use them, and can't seem to find a way to do
it.

The problem is that subroutines are usually stored (and looked up from) in
the lexical pad (ie the same as my-variables), and those lexpads
are immutable at run time.

Today I found a solution that lets you dynamically install subroutines with
a computed name into a module, and you can then use that module
from elsewhere, and have all the generated subroutines available.

Inside the module first we need a BEGIN block, so that the
is export trait will run while the module is being compiled, and
thus knows which module to associate the subroutine to.

Next comes the actual code object that is to be installed. Since the
export trait inspects the name of the subroutine, we need to give
it one. Doing that dynamically can be done by overriding the name
method, here by mixing in a role with such a method into the code object.

Finally comes the part where the export trait is applied. The code here
uses knowledge of the calling conventions that hide behind a trait.

A different script can then write

use A;
foo();

And access the dynamically exported sub just like any other.

In future there will hopefully be much nicer APIs for this kind of
fiddling, but for now I'm glad that a workaround has been found.