内省模块/类/等的替代语法

时间:2018-08-21 22:26:05

标签: syntax perl6 symbolic-references

出于工作目的,我正在将框架从Perl5重写为Perl6。在某些地方,我需要通过执行其他模块/类可能提供的公共sub来收集信息。否则他们可能不会。因此,有必要找出sub是否存在。当直接引用模块(Foo::<&my-sub>)或字符串中的符号名称(&::(“ Foo”):: my-sub)时,这没什么大不了的。但是为了简单起见,我想允许按原样传递模块名称(假设collector是收集信息的方法):

self.collector( Foo );

Foo可能是以下位置:

module Foo {
    use Bar;
    use Baz;
    our sub my-sub { Bar, 'Baz' }  
}

这是我在Perl6语法中缺少重要内容的地方,因为以下原因:

method collector ( $mod ) {
    my $mod-name = $mod.WHO;
    my @mods;
    with &::($mod-name)::my-sub {
         @mods.push: &$_();
    }
}

目前是我执行任务的唯一方法。

我还没有尝试类型捕获。我猜应该能按预期工作。因此,问题更多是关于扩展我的语法知识。

1 个答案:

答案 0 :(得分:3)

与Vadim交换意见的最终解决方案。可以说是疯了。他们认为这很漂亮。我该和谁争论呢? .oO(哈哈,呵呵,嘻嘻...)

my $pkg-arg = (Int, 'Int').pick;
my \pkg-sym = $pkg-arg && ::($pkg-arg);
my \sub-ref = &pkg-sym::($subname);

有两种明显有用的方法来引用程序包:

  • 其符号名称。 Int是Int类的符号名称。

  • 其字符串名称。 'Int'是Int类的字符串名称。

瓦迪姆(Vadim)很想为两者解决。

在此答案的解决方案中,我通过随机选择一个并将其分配给$pkg-arg来模拟两种类型的参数:

my $pkg-arg = (Int, 'Int').pick;

现在我们需要归一化。如果我们有一个象征性的名字,那很好。但是,如果它是一个字符串名称,我们需要将其转换为符号名称。

Vadim在有关其问题的评论中展示了几种方法来做到这一点。此解决方案使用第三个选项:

my \pkg-sym = $pkg-arg && ::($pkg-arg);

如果$pkg-arg是符号名称,它将是False。对于False LHS,&&短路并返回其LHS。如果$pkg-arg是字符串名称,则&&将返回其RHS,即::($pkg-arg),这是使用$pkg-arg作为字符串名称的符号查找。

结果是pkg-sym最终包含一个软件包符号名称(如果查找未能找到匹配的符号名称,则返回Failure)。

离开最后一行。那会在包$subname中寻找一个名为pkg-sym的子程序:

my \sub-ref = &pkg-sym::($subname);

需要&来确保将RHS视为参考,而不是尝试调用例程。并且pkg-sym必须是无符号标识符,否则代码将无法工作。

这三行代码sub-ref的末尾包含Failure或对有用子的引用。