我正在寻求在子模块中重复使用与其父模块中相同的角色/类名称。你知道,就像一个专业。
\nuse Dan目的是通过简单地更改为use Dan::Pandas顶部,能够为父系列和子系列变体重复使用相同的脚本代码。
我试图坚持角色而不是类组成,以便可以将行为应用于其他对象,例如。class GasBill does Series;
这是 MRE:
\nme@ubuntu:~/spike# tree\n.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 lib\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 Dan\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 Pandas.rakumod\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 Dan.rakumod\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 spike.raku\nRun Code Online (Sandbox Code Playgroud)\n丹·拉库莫德:
\n 1 unit module Dan;\n 2 \n 3 role Series is export {\n 4 method no { "no" }\n 5 }\nRun Code Online (Sandbox Code Playgroud)\n熊猫.rakumod:
\n 1 unit module Dan::Pandas;\n 2 \n 3 use Dan;\n 4 \n 5 role Series does Dan::Series is export {\n 6 method yo { "yo" }\n 7 }\nRun Code Online (Sandbox Code Playgroud)\n尖峰乐:
\n 1 use lib './lib';\n 2 use Dan::Pandas;\n 3 \n 4 my $s = Series.new; #version 1 \n 5 #my $s = Dan::Pandas::Series.new; #version 2 "fqm"\n 6 \n 7 say $s.no, $s.yo, $s.^name;\nRun Code Online (Sandbox Code Playgroud)\n我的版本 1 说:
\nNo appropriate parametric role variant available for 'Dan::Series':\n Ambiguous call to '(Dan::Series)'; these signatures all match:\n (::$?CLASS ::::?CLASS Mu $)\n (::$?CLASS ::::?CLASS Mu $)\n in block <unit> at spike.raku line 4\nRun Code Online (Sandbox Code Playgroud)\n我的版本 2 说:
\nCould not find symbol '&Series' in 'Dan::Pandas'\n in block <unit> at spike.raku line 5\nRun Code Online (Sandbox Code Playgroud)\n我相信 raku 确实有办法做到这一点,但如果我能解决的话那就该死了!
\n如果我理解正确,您不需要/不想在最终模块中使用非专业角色(也就是说,您没有使用\xe2\x80\x93中Series定义的角色,您只使用专门定义在)。那是对的吗?Dan.rakumodspike.rakuSeriesPandas.rakumod
如果是这样,解决方案很简单:只需不要exportfrom \xe2\x80\x93 它仍然有作用域(角色的默认值),因此您仍然可以按照当前的方式使用它()。但是,由于它没有导出,因此不会与无前缀的.SeriesDan.rakumodourPandas.rakumodDan::SeriesSeries
TL;DR您需要一个解决方案来避免两个角色具有相同的全名。
role R {}
role R {}
R.new
Run Code Online (Sandbox Code Playgroud)
显示:
No appropriate parametric role variant available for 'R':
Ambiguous call to '(R)'; these signatures all match:
(::$?CLASS ::::?CLASS Mu $)
(::$?CLASS ::::?CLASS Mu $)
Run Code Online (Sandbox Code Playgroud)
(有关错误消息的更多讨论,请参阅编写存根角色时的内部引用警告。)
只是Dan。
Dan.rakumod:
unit module Dan;
role Series is export { method no { "no" } }
Run Code Online (Sandbox Code Playgroud)
spike.raku:
use lib '.';
use Dan;
my $s = Series.new;
.say for $s.?no, $s.?yo, $s.^name;
Run Code Online (Sandbox Code Playgroud)
运行spike显示:
no
Nil
Dan::Series
Run Code Online (Sandbox Code Playgroud)
介绍Dan::Pandas。
改变Dan这样的变体模块就可以use不需要将的不合格符号导入 到它们的词法范围中。Dan Series
(因为 elseDan的非限定Series符号最终位于它们的词法范围以及它们自己的非限定Series符号中,并且您会收到“不明确的调用”错误。)
Dan:
unit module Dan;
role Series is export { method no { "no" } }
class Dan::Variant-Export-Dummy-Type is export(:Variant-Exports) {}
Run Code Online (Sandbox Code Playgroud)
更改是最后一行,一个带有新导出标签的虚拟声明。(以更简洁的方式介绍新标签,留给读者作为练习。)
Dan::Pandas:
unit module Dan::Pandas;
use Dan :Variant-Exports;
role Series does Dan::Series is export { method yo { "yo" } }
Run Code Online (Sandbox Code Playgroud)
更改是:Variant-Exports在use Dan ...语句中使用新标签。这会停止以该非限定名称将Dan角色Series导入到Dan::Pandas.
用户程序现在将按预期/想要的方式工作。
只需更改use以下语句spike.raku:
use lib '.';
use Dan::Pandas;
my $s = Series.new;
.say for $s.?no, $s.?yo, $s.^name;
Run Code Online (Sandbox Code Playgroud)
仅对用户程序进行此更改即可运行:
no
yo
Dan::Pandas::Series
Run Code Online (Sandbox Code Playgroud)
请注意,使用这些模块的程序不需要了解标签:Variant-Exports。Dan这只是模块和等模块的内部细节Dan::Pandas,可以让它们避免本答案开头所示的意外角色变体重复问题。