我正在制作一个具有多模块文件的模块, 并在不同模块中使用角色时遇到了这个问题。
例如,我们有两个模块Foo和Bar,每个模块中都有一个角色。
module Foo {
role foo is export {
}
}
module Bar {
import Foo;
role bar is export does foo {
}
}
import Foo;
import Bar;
sub f(foo \k) { }
f(bar.new);
我认为代码很好,但是rakudo说它认为bar不是foo,因此拒绝编译。
这是怎么了?
答案 0 :(得分:4)
foo
后的符号import
不是=:=
到Foo::foo
,并且在智能匹配中不接受后者。在我看来,这似乎是一个错误,并且大概与发生的事情有关:
module Foo {
role foo is export { }
.say for foo.^name, Foo::foo.^name,
Foo.WHICH, foo.WHICH, Foo::foo.WHICH,
foo.isa(Foo::foo),
Foo::foo.isa(foo),
foo.does(Foo::foo),
Foo::foo.does(foo),
foo ~~ Foo::foo,
Foo::foo ~~ foo,
}
import Foo;
.say for foo.^name, Foo::foo.^name,
Foo.WHICH, foo.WHICH, Foo::foo.WHICH,
foo.isa(Foo::foo),
Foo::foo.isa(foo),
foo.does(Foo::foo),
Foo::foo.does(foo),
foo ~~ Foo::foo,
Foo::foo ~~ foo,
Foo::foo
Foo::foo
Foo|U64545472
Foo::foo|U64545856
Foo::foo|U64545856
False
False
True
True
True
True
Foo::foo
Foo::foo
Foo|U64545472 <^-- all good so far
Foo::foo|U64545616 <--- uhoh
Foo::foo|U64545856
False
False
True
True
True
False <-- presumably a consequence of uhoh
如果没人能击败我,并且在接下来的几天里我不会提出错误,那么没人会证明它不是错误。
答案 1 :(得分:4)
对我来说,这似乎是个错误。一些进一步的调查:
module Foo {
role Bar is export {}
}
module Quux {
import Foo;
constant Barr = Bar;
role Baz does Bar is export {}
role Bazz does Foo::Bar is export {}
}
import Foo;
import Quux;
# these are all the same:
say Foo::EXPORT::ALL::Bar.WHICH;
say Quux::Barr.WHICH;
say Bar.WHICH;
# but different from our original type object!?!
say Foo::Bar.WHICH;
# now it gets weird:
say Baz ~~ Bar; # True
say Baz.new ~~ Bar; # False
say Baz ~~ Foo::Bar; # False
say Baz.new ~~ Foo::Bar; # True
# however, these all 'work':
say Bazz ~~ Bar; # True
say Bazz.new ~~ Bar; # True
say Bazz ~~ Foo::Bar; # True
say Bazz.new ~~ Foo::Bar; # True
就目前而言,似乎最好仅从另一个模块角色的完全限定的公共版本中派生新角色,而不是从导出的角色中派生:导出似乎创建了一个新类型的对象,该对象与智能匹配/类型检查奇怪地交互...
答案 2 :(得分:2)
让我看看我是否可以引导@raiph并以最佳方式回答这个问题。这里有几个错误。
使用import
import
的主要用例正是您在此处使用的用例;是described in the documentation。但是,更好的做法是将模块放入不同的文件(与模块同名)中,而改为使用use
。 use
会将所有内容导入并包含到名称空间中。 use
加载(通过need
),然后仅一次导入模块。
使用单位保存花括号
unit
基本上是语法花括号,用于保存括号。因此,前两个文件将变为:
Foo.pm6
unit module Foo;
role foo is export {
}
Bar.pm6
unit module Bar;
use Foo;
role bar is export does foo {}
use
中的Foo
直接导入foo
符号,它可以用作角色。
什么是角色
最后但并非最不重要的一点是,混入do的角色实际上是一个“ does”声明。这不是“是”声明。因此bar
可以do
foo,但不是foo
。这使得最后一个文件是这样的:
use-foo-bar.p6
:
use Foo;
use Bar;
sub f(bar \k) { }
f(bar.new);
请注意,我使用的是bar \k
而不是foo \k
。如果没有,错误将是:Type check failed in binding to parameter 'k'; expected Foo::foo but got Bar::bar (Bar::bar.new)
返回原始帖子
哪里出了问题,只是子声明,应该是:
sub f(bar \k) { }
由于上面最后一节中的解释。但是,我需要检查一下程序的其余部分才能找到答案。