在子模块中重用父符号
我正在寻求在子模块中重复使用与其父模块中相同的角色/类名称。你知道,就像一个专业。
目的是通过简单地将顶部的 use Dan
更改为 use Dan::Pandas
,能够为父系列和子系列变体重复使用相同的脚本代码。
我试图坚持角色而不是类组成,以便可以将行为应用于其他对象,例如。 class GasBill does Series;
这是 MRE:
me@ubuntu:~/spike# tree
.
├── lib
│ ├── Dan
│ │ └── Pandas.rakumod
│ └── Dan.rakumod
└── spike.raku
Dan.rakumod:
1 unit module Dan;
2
3 role Series is export {
4 method no { "no" }
5 }
Pandas.rakumod:
1 unit module Dan::Pandas;
2
3 use Dan;
4
5 role Series does Dan::Series is export {
6 method yo { "yo" }
7 }
spike.raku:
1 use lib './lib';
2 use Dan::Pandas;
3
4 my $s = Series.new; #version 1
5 #my $s = Dan::Pandas::Series.new; #version 2 "fqm"
6
7 say $s.no, $s.yo, $s.^name;
我的版本 1 说:
No appropriate parametric role variant available for 'Dan::Series':
Ambiguous call to '(Dan::Series)'; these signatures all match:
(::$?CLASS ::::?CLASS Mu $)
(::$?CLASS ::::?CLASS Mu $)
in block <unit> at spike.raku line 4
我的版本 2 说:
Could not find symbol '&Series' in 'Dan::Pandas'
in block <unit> at spike.raku line 5
我相信 raku 确实有办法做这个,但是该死的,如果我能解决的话!
I am seeking to re-use the same role/class names in a child module as in its parent. You know, like a specialization.
The aim is to be able to re-use the same script code for both the parent and child Series variants by simply changing use Dan
to use Dan::Pandas
at the top.
I am trying to stick to role rather than class compostion where I can so that the behaviours can be applied to other objects with eg. class GasBill does Series;
Here is the MRE:
me@ubuntu:~/spike# tree
.
├── lib
│ ├── Dan
│ │ └── Pandas.rakumod
│ └── Dan.rakumod
└── spike.raku
Dan.rakumod:
1 unit module Dan;
2
3 role Series is export {
4 method no { "no" }
5 }
Pandas.rakumod:
1 unit module Dan::Pandas;
2
3 use Dan;
4
5 role Series does Dan::Series is export {
6 method yo { "yo" }
7 }
spike.raku:
1 use lib './lib';
2 use Dan::Pandas;
3
4 my $s = Series.new; #version 1
5 #my $s = Dan::Pandas::Series.new; #version 2 "fqm"
6
7 say $s.no, $s.yo, $s.^name;
My version 1 says:
No appropriate parametric role variant available for 'Dan::Series':
Ambiguous call to '(Dan::Series)'; these signatures all match:
(::$?CLASS ::::?CLASS Mu $)
(::$?CLASS ::::?CLASS Mu $)
in block <unit> at spike.raku line 4
My version 2 says:
Could not find symbol '&Series' in 'Dan::Pandas'
in block <unit> at spike.raku line 5
I am trusting that raku does have a way to do this, but darned if I can work it out!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
TL;DR 您需要一个解决方案来避免两个角色具有相同的全名。
高尔夫
显示:(
请参阅编写存根角色时的直觉引用警告对错误消息进行更多讨论。)
解决方案
Just
Dan
。Dan.rakumod
:spike.raku
:运行
spike
显示:<前><代码>否
零
丹::系列
Introduce
Dan::Pandas
。更改
Dan
,以便变体模块可以使用
它而无需它们导入Dan< /code> 的非限定
Series
符号进入其词法范围。(因为否则
Dan
的未限定Series
符号最终会位于其词法范围以及其自己的中em> 不合格的Series
符号,并且您会收到“不明确的调用”错误。)丹
:更改是最后一行,一个带有新导出标记的虚拟声明。 (以更简洁的方式介绍新标签,留给读者作为练习。)
丹::熊猫
:更改是使用新的
:Variant-Exports
标记和use Dan ...
语句。这会阻止Dan
的Series
角色以该非限定名称导入Dan::Pandas
。用户程序现在将按预期/想要的方式工作。
只需更改
spike.raku
中的use
语句即可:仅对用户程序进行此更改即可运行:
<前><代码>否
哟
丹::熊猫::系列
请注意,使用这些模块的程序无需了解
:Variant-Exports
标记。这只是Dan
模块和Dan::Pandas
等模块的内部细节,可以让它们避免本答案开头所示的意外角色变体重复问题。< /p>TL;DR You need a solution that avoids having two roles with the same full name.
Golf
displays:
(See Gut-referencing warning when composing stubbed role for a bit more discussion of the error message.)
A solution
Just
Dan
.Dan.rakumod
:spike.raku
:Running
spike
displays:Introduce
Dan::Pandas
.Alter
Dan
so variant modules canuse
it without them importingDan
's unqualifiedSeries
symbol into their lexical scopes.(Because otherwise
Dan
's unqualifiedSeries
symbol ends up being in their lexical scopes as well as their own unqualifiedSeries
symbol, and you get the "Ambiguous call" error.)Dan
:The change is the last line, a dummy declaration with a new export tag. (Introducing the new tag some cleaner way is left as an exercise for readers.)
Dan::Pandas
:The change is using the new
:Variant-Exports
tag with theuse Dan ...
statement. This stopsDan
'sSeries
role being imported under that unqualified name intoDan::Pandas
.User programs will now work as expected/wanted.
Just change the
use
statement inspike.raku
:Running with just this change for user programs:
Note how there's no need for programs using using these modules to know about the
:Variant-Exports
tag. That's just an internal detail of theDan
module and theDan::Pandas
etc modules that lets them avoid the unintended role variant duplication problem shown at the start of this answer.如果我理解正确,您不需要/不想在最终模块中使用非专业角色(也就是说,您没有使用
Dan.xml 中定义的
– 您仅使用Series
)。spike.raku
中的 rakumodPandas.rakumod
中定义的专用Series
)。这是正确的吗?如果是这样,解决方案很简单:只需不要从
Dan.rakumod
中导出
Series
– 它仍然是我们的
范围(角色的默认值),因此您仍然可以按照当前的方式在Pandas.rakumod
中使用它 (Dan::Series
)。但是,由于它未导出,因此不会与无前缀的Series
产生名称冲突。If I'm understanding correctly, you don't need/want to use the non-specialized role in the final module (that is, you aren't using the
Series
defined inDan.rakumod
inspike.raku
– you're only using the specializedSeries
defined inPandas.rakumod
). Is that correct?If so, the solution is simple: just don't
export
theSeries
fromDan.rakumod
– it's stillour
scoped (the default for roles) so you can still use it inPandas.rakumod
exactly the way you currently do (Dan::Series
). But, since it's not exported, you it won't create a name clash with the non-prefixedSeries
.我的解决方案
采纳 @codesections [FQM 可以在没有
is export
的情况下使用] 和 @raiph [您可以使用例如is export(:ALL)
限定导出的建议],然后 - 是的 - 有一个巧妙的方法可以做到这一点。即。 https://docs.raku.org/language/modules#Exporting_and_selective_importing
事实证明这是低接触(只需更改两行),并且正如我最初希望的那样,raku 设计师已经预料到了这一点。
这是我的OP调整后的代码...
Dan.rakumod:
Pandas.rakumod(无变化):
spike.raku:
My Solution
Taking the advice of @codesections [that FQMs can be used without
is export
] and @raiph [that you can qualify the export with e.g.is export(:ALL)
], then - yes - there is a neat way to do this.viz. https://docs.raku.org/language/modules#Exporting_and_selective_importing
Turns out that this is low touch (just change two lines) and, as I originally hoped, something that raku designers have anticipated.
Here is the code from my OP adjusted...
Dan.rakumod:
Pandas.rakumod (no change):
spike.raku: