在两个模块之间使用角色时出现问题

时间:2018-09-09 15:16:15

标签: perl6

我正在制作一个具有多模块文件的模块, 并在不同模块中使用角色时遇到了这个问题。

例如,我们有两个模块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,因此拒绝编译。

这是怎么了?

3 个答案:

答案 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。但是,更好的做法是将模块放入不同的文件(与模块同名)中,而改为使用useuse会将所有内容导入并包含到名称空间中。 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) { }

由于上面最后一节中的解释。但是,我需要检查一下程序的其余部分才能找到答案。