Как сделать modulino в Perl6?

Я хочу сделать modulino (файл, который может работать как модуль или скрипт) в Perl6.

следующий код "обрабатывает" имена файлов из командной строки:

sub MAIN ( *@filenames )
{
    for @filenames -> $filename
    {
        say "Processing $filename";
    }
}

сохранение этого как main.pm6 Я могу запустить его и он работает:

perl6 main.pm6 hello.txt world.txt
Processing 'hello.txt'
Processing 'world.txt'

Итак, я хочу, чтобы это был модуль, чтобы я мог добавлять функции и упрощать тестирование. Однако, когда я добавляю module объявление к нему, оно больше не выводит что угодно:

module main;
sub MAIN ( *@filenames )
{
    for @filenames -> $filename
    {
        say "Processing '$filename'";
    }
}

что приводит ни к чему выходу:

perl6 main.pm6 hello.txt world.txt

Итак, как я могу построить modulino в Perl6?

я использую Perl6, работающий на MoarVM С январь 2015 года выпуск Rakudo Star.

обновление:

когда я пытаюсь обернуть модуль в фигурные скобки:

module main
{
    sub process (@filenames) is export
    {
        for @filenames -> $filename
        {
            say "Processing '$filename'";
        }
    }
};

sub MAIN ( *@filenames )
{
    process(@filenames)
}

Я также получаю ошибки:

===SORRY!=== Error while compiling main.pm6
Undeclared routine:
    process used at line 14. Did you mean 'proceed'?

1 ответов


на MAIN sub должен быть объявлен вне модуля, но он все равно должен быть в состоянии видеть process.

есть несколько способов достичь этого, например, не объявляя модуль вообще

sub process(@filenames) {
    for @filenames -> $filename {
        say "Processing '$filename'";
    }
}

sub MAIN(*@filenames) {
    process(@filenames);
}

делая process our-scoped и называя его своим длинным именем

module main {
    our sub process(@filenames) {
        for @filenames -> $filename {
            say "Processing '$filename'";
        }
    }
}

sub MAIN(*@filenames) {
    main::process(@filenames);
}

или путем экспорта process и импортировать его в тело MAIN

module main {
    sub process(@filenames) is export {
        for @filenames -> $filename {
            say "Processing '$filename'";
        }
    }
}

sub MAIN(*@filenames) {
    import main;
    process(@filenames);
}

на мой взгляд, наиболее подходящим вариантом является добавление MAIN модуль и импортируйте его в основную строку сценария. Таким образом, все объявленное в модуле отображается в MAIN без необходимости явно экспортировать все:

module main {
    sub process(@filenames) {
        for @filenames -> $filename {
            say "Processing '$filename'";
        }
    }

    sub MAIN(*@filenames) is export(:MAIN) {
        process(@filenames);
    }
}

import main :MAIN;

обратите внимание, что это не экспорт MAIN по умолчанию, то есть пользователи вашего модуля получат его, только если они предоставят :MAIN тег.