Как правильно загружать модули Raku с помощью rakudo-star?

У меня есть следующий проект

$ tree
.
├── lib
│   └── MyModule.raku
└── main.raku

$ cat lib/MyModule.raku
use v6;
unit module MyModule;
sub hello { say 'hello' }

$ cat lib/main.raku
use v6;
use MyModule;
MyModule.hello();

Я хочу запустить main.raku, используя последнюю версию rakudo-star изображение. Однако происходит следующее

$ docker run -i --rm -u $(id -u) \
--workdir /work \
--volume  $PWD:/work \
--entrypoint bash \
rakudo-star perl6 -I ./lib main.raku
===SORRY!===
Could not find MyModule at line 3 in:
    file#/work/lib
    inst#/.perl6
    inst#/usr/share/perl6/site
    inst#/usr/share/perl6/vendor
    inst#/usr/share/perl6
    ap#
    nqp#
    perl5#

Я тоже пробовал вставить use lib '/work/lib' перед use MyModule в main.raku с тем же результатом.

2 ответа

Решение

Есть несколько проблем.

  1. Модули не заканчиваются на .raku. Они заканчиваются.rakumod или .pm6(теперь).
    (Технически после установки не имеет значения, какое расширение будет, если оно правильно объявлено вMETA6.json.)

  2. По умолчанию подпрограммы имеют лексическую область видимости (my), а также по умолчанию не экспортируются.
    Так что нет возможности получить доступhello() вне модуля он определен в.

  3. У модулей нет методов, поэтому вы не можете вызывать helloкак метод.
    Даже если бы у них были методы, они бы не начали сsub ключевое слово.


Вы можете глобально охватить подпрограмму с помощью our:

lib/MyModule.rakumod

use v6.d;
unit module MyModule;

our sub hello () { say 'hello' }
#^
# \
#  globally scoped

main.raku

use v6.d;
# use lib './lib';
use module MyModule;

MyModule::hello();
#       ^^
#        \
#         namespace delimiter

Вместо этого вы можете экспортировать его:

lib/MyModule.rakumod

use v6.d;
unit MyModule;

#             mark for export
#            v-------v
sub hello () is export {
    say 'hello'
}

main.raku

use v6.d;
# use lib './lib';
use MyModule;

hello();

В дополнении к is export, есть и другие, более тонкие способы экспорта.

Если вы собираетесь экспортировать, я бы порекомендовал сделать его глобальным с помощью our. Таким образом, если кто-то использует ваш модуль, но не хочет импортировать ваши подпрограммы; они все еще имеют к ним доступ.

В новых версиях Раку используется .rakumodкак расширение файла для модулей. Старший.pm6расширение все еще поддерживается. Более подробную информацию о новых расширениях файлов можно найти в билете Path-to-Raku. Более подробная информация о модулях доступна в документации по raku.

Другие вопросы по тегам