在子模块中重用父符号

p6s*_*eve 5 oop raku

我正在寻求在子模块中重复使用与其父模块中相同的角色/类名称。你知道,就像一个专业。

\n

use Dan目的是通过简单地更改为use Dan::Pandas顶部,能够为父系列和子系列变体重复使用相同的脚本代码。

\n

我试图坚持角色而不是类组成,以便可以将行为应用于其他对象,例如。class GasBill does Series;

\n

这是 MRE:

\n
me@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\n
Run 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 }\n
Run 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 }\n
Run 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;\n
Run Code Online (Sandbox Code Playgroud)\n

我的版本 1 说:

\n
No 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\n
Run Code Online (Sandbox Code Playgroud)\n

我的版本 2 说:

\n
Could not find symbol '&Series' in 'Dan::Pandas'\n  in block <unit> at spike.raku line 5\n
Run Code Online (Sandbox Code Playgroud)\n

我相信 raku 确实有办法做到这一点,但如果我能解决的话那就该死了!

\n

cod*_*ons 5

如果我理解正确,您不需要/不想在最终模块中使用非专业角色(也就是说,您没有使用\xe2\x80\x93中Series定义的角色,您只使用专门定义在)。那是对的吗?Dan.rakumodspike.rakuSeriesPandas.rakumod

\n

如果是这样,解决方案很简单:只需不要exportfrom \xe2\x80\x93 它仍然有作用域(角色的默认值),因此您仍然可以按照当前的方式使用它()。但是,由于它没有导出,因此不会与无前缀的.SeriesDan.rakumodourPandas.rakumodDan::SeriesSeries

\n

  • @p6steve 其他脚本仍然可以“使用 Dan”,就像“Pandas.rakumod”一样 - 他们只需要使用完整的“Dan::Series”名称(而不仅仅是“Series”)即可参考 `Dan::Series` (同样,就像 `Pandas.rakumod` 一样)。如果这太冗长,他们总是可以在文件中的“use”语句之后使用“constant Series = Dan::Series”之类的别名。 (2认同)

rai*_*iph 5

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)

(有关错误消息的更多讨论,请参阅编写存根角色时的内部引用警告。)

一个办法

  1. 只是Dan

  2. 介绍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-Exportsuse Dan ...语句中使用新标签。这会停止以该非限定名称将Dan角色Series导入到Dan::Pandas.

  3. 用户程序现在将按预期/想要的方式工作。

    • 只需更改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-ExportsDan这只是模块和等模块的内部细节Dan::Pandas,可以让它们避免本答案开头所示的意外角色变体重复问题。