Home > Raku > Double inspiration

Double inspiration

Quite a few of the posts prior to this one where inspired by a post of fellow blogger. I would like to double down on that today. Vadim wrangled with symbols and Fabio enjoyed renaming them. Having struggled with packages in the past, Vadim’s post was very helpful in making me realise, .HOW is how I can get hold of the object that is the package. And if Perl can do it, there is surely no way to stop Raku to have the same capability.

We want to re-export functions while changing their name. Just adding a prefix will do for now. That presents the first problem. Currently, there is no way to get named arguments to use handed to sub EXPORT. Any Hash will also be gobbled up. All we have are positional parameters. Since Raku is omni-paradigmatic, that wont pose a challenge.

use Transport {'WWW', :prefix<www->};

We can execute that block and use destructuring to get hold of the positional and any colonpair.

use v6.d;

sub EXPORT(&args) {
    my ($module-name, *%tags) = args;

    my \module = (require ::($module-name));
    my %exports = module.WHO<EXPORT>.WHO<DEFAULT>.WHO.&{.keys Z=> .values};
    my %prefixed-exports = %exports.map: { .key.substr(0, 1) ~ %tags<prefix> ~ .key.substr(1..*) => .value };

    %prefixed-exports.Map
}

The only trouble I had was with .WHO being a macro and not a method of Mu. So we need a symbol to hold the package, which is returned by require.

dd &www-jpost;
# OUTPUT: Sub jpost = sub jpost (|c) { #`(Sub|94403524172704) ... }

I didn’t turn this into a proper module, yet. This needs more reading (what the Sub::Import is actually being used for) and thinking. A 1:1 translation from Perl seems to be the easy way and thus is likely not the most correct.

Categories: Raku
  1. Clifton Wood
    October 10, 2021 at 09:51

    Then wouldn’t an alias mechanism be as simple as adding an alias named parameter (which is a hash containing original name => alias name pairs), and a proper handler in EXPORT.

    Something akin to this:

    sub EXPORT(&args) {
    my ($module-name, *%tags) = args;

    my \module = (require ::($module-name));
    my %exports = module.WHO.WHO.WHO.&{.keys Z=> .values};
    my %prefixed-exports = %exports.map: {
    .key.substr(0, 1) ~ %tags ~ .key.substr(1..*) => .value
    }
    if %tags {
    for %exports.pairs {
    if %tags{.key} {
    %prefixed-exports{%tags{.key}} => .value
    }
    }
    }

    %prefixed-exports.Map
    }

    So now this:

    use Transport { ‘WWW’, :prefix. :alias({ get-request => ‘GET’ }) }

    Would provide get-request() as www-get-request() and also GET()

    I think I like this idea!

  1. October 11, 2021 at 16:46

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: