使用 rakudo-star 加载 Raku 模块的正确方法是什么?

lit*_*tle 7 rakudo-star raku

我有以下项目

$ 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();
Run Code Online (Sandbox Code Playgroud)

我想使用最新的rakudo-star 图像运行 main.raku 。但是会出现以下情况

$ 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#
Run Code Online (Sandbox Code Playgroud)

我之前也试过在 main.raku 中插入use lib '/work/lib'use MyModule结果相同。

Val*_*kas 5

新的 Raku 版本使用.rakumod模块的as 文件扩展名。.pm6仍然支持旧的扩展。有关新文件扩展名的更多信息可以在Path-to-Raku票证中找到。raku 文档中提供了有关模块的更多信息。


Bra*_*ert 5

有几个问题。

  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
Run Code Online (Sandbox Code Playgroud)

main.raku

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

MyModule::hello();
#       ^^
#        \
#         namespace delimiter
Run Code Online (Sandbox Code Playgroud)

您可以将其导出:

lib/MyModule.rakumod

use v6.d;
unit MyModule;

#             mark for export
#            v-------v
sub hello () is export {
    say 'hello'
}
Run Code Online (Sandbox Code Playgroud)

main.raku

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

hello();
Run Code Online (Sandbox Code Playgroud)

除此之外is export,还有其他更细粒度的导出方式

我建议,如果您要导出,还应使用our. 这样,如果有人使用您的模块,但不想导入您的子程序;他们仍然可以访问它们。