Search code examples
compilationmetaprogrammingrakucompile-timerakudo

Accessing a Variable at compile time


The will trait gives compile-time access to the Variable on which it's called. Are there other ways to access the Variables that will be installed in a given lexical scope? (I know I can access the Scalars at runtime, but I'm trying to get at the Variables).

In particular, I would like to be able to do something like the following (which doesn't work):

multi trait_mod:<is>(Sub \fn, :$foo) {
    for fn.lexical_variables { #`(do stuff) }
}

Is there any way to do so?


Solution

  • Not at present, however it should be possible in a future Raku language version. Work is taking place to define a standard AST for the Raku language (currently known as "RakuAST"), and to rewrite the compiler frontend to work in terms of it. Once that is done, it will be exposed in a number of places. Macros are the most obvious consumers, however it's also planned:

    • To make the AST of a block or routine available from traits, in order that traits can inspect and perhaps even modify the AST
    • To introduce custom compiler passes, which will be modules that are given access to the entire AST of the scope that they are imported into

    The first of these would seem to satisfy your use case. Going on current proposed API it could look something like this:

    multi trait_mod:<is>(Sub $fn, :$foo!) {
        for $fn.ast.ast-lexical-declarations {
            say "Name: " ~ .lexical-name;
            when RakuAST::VarDeclaration::Simple { #`( my $x / state $x / ... ) }
            when RakuAST::VarDeclaration::Term { #`( my \x = ... ) }
            # Others, depending if you care about parameters, placeholder params, implicits, etc.
        }
    }