Håkon Hægland
Håkon Hægland

Reputation: 40778

How to autoload a module subroutine?

In Perl 5, a module can declare an AUTOLOAD() subroutine that will be called if an undefined subroutine is called. Similarly in Perl 6 classes there is a FALLBACK() method. But I could not find anything similar to FALLBACK() for modules.

Here is an example of a use case: I would like to write a new module MyModule that exports all subroutines that another module OtherModule exports, and then forwards all subroutine calls to those exported methods (not yet defined) in MyModule to the corresponding subroutine in OtherModule. I think I can get the exported symbols from OtherModule using CompUnit::Util.

Question: How can I implement the Perl 5 autoload mechanism in Perl 6?

Upvotes: 4

Views: 242

Answers (1)

Christoph
Christoph

Reputation: 169833

Lexical names are resolved statically, so I'm not sure how to implement AUTOLOAD without some deep magic.

Regarding your specific example, I'm also not quite sure what the 'proper' way to do so would be, but here's a 'dirty' solution that seems to work, replacing a sub &foo exported by a module Foo:

# get all subroutines exported by Foo by default
BEGIN my @reex = do {
    use Foo;
    MY::.pairs.grep(*.key.starts-with('&'));
}

# export our replacement subroutine (also in the default namespace)
sub foo is export {
    say "new foo";
}

# re-export subroutines lacking a replacement
# placed at the end of the module so EXPORT will have been populated
BEGIN EXPORT::DEFAULT::{.key} //= .value
    for @reex;

Upvotes: 4

Related Questions