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



出于我的工作目的,我正在将框架从 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: &$_();
}
}

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

不过,我还没有尝试类型捕获。我猜应该按预期工作。所以,问题更多的是关于扩展我对语法的了解。

与瓦迪姆交流的最终解决方案在对他们问题的评论中。可以说是疯了。他们认为它很漂亮。我该和谁争论?.oO(哈哈,嘿嘿,嘿嘿...

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

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

  • 它的象征性名称。Int是 Int 类的符号名称。

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

瓦迪姆合理地想要一个解决方案。

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

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

现在我们需要规范化。如果我们有一个象征性的名字,我们就可以走了。但如果它是一个字符串名称,我们需要将其转换为符号名称。

瓦迪姆在对他们问题的评论中展示了几种方法。此解决方案使用第三个选项:

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

如果$pkg-arg是符号名称,则False。使用FalseLHS 时,&&短路并返回其 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或对所需子的引用。

相关内容

  • 没有找到相关文章

最新更新