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

Problem when using role between two module

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

比如我们有两个模块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 并拒绝编译。

这里有什么问题吗?

让我看看我是否可以引导@raiph 并以最好的方式回答这个问题。这里有几个错误。

使用import

import 的主要用例正是您在此处所做的;它是 described in the documentation. However, it's a better practice to put modules in different files (with the same name as the module) and go for use instead. use which imports and includes everything into the namespace. 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 {}

Foouse直接导入foo符号,可以作为作用

什么是角色

最后但同样重要的是,混合在 does 中的角色实际上是一个 "does" 声明。这不是 "is-a" 声明。所以 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)

回原post

错误的只是子声明,它应该是:

sub f(bar \k) { }

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

import 之后的符号 foo 不是 =:=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

我会在接下来的几天内提交一个错误,如果没有人比我更早,也没有人说明为什么它不是错误。

我觉得这像是一个错误。进一步调查:

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

目前,似乎最好只从另一个模块角色的完全限定 public 版本派生新角色,而不是导出角色:导出似乎创建了一个新类型的对象,它与智能 matching/type正在检查...