我正在为我的工作重写从Perl5到Perl6的框架.在某些地方,我需要通过执行他们可能提供的公共子来从其他模块/类中收集信息;或者他们可能没有.因此,有必要找出子是否存在.当直接引用模块(Foo ::<& my-sub>)或字符串中的符号名称(&::(“Foo”):: my-sub)时,这不是什么大问题.但为了简单起见,我想允许按原样传递模块名称(假设收集器是收集信息的方法):
self.collector( Foo );
Foo可能如下:
module Foo { use Bar; use Baz; our sub my-sub { Bar,'Baz' } }
method collector ( $mod ) { my $mod-name = $mod.WHO; my @mods; with &::($mod-name)::my-sub { @mods.push: &$_(); } }
目前是我可以执行任务的唯一方法.
虽然我没有尝试类型捕获.我想,应该按预期工作.所以,问题更多的是扩展我的语法知识.
解决方法
与Vadim交换的最终解决方案是对他们问题的评论.这可能是疯了.他们认为这很美.我该与谁争辩? .oO(哈哈,hoho,heehee ……)
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.使用假LHS&&短路并返回其LHS.如果$pkg-arg是一个字符串名称,那么&&将返回其RHS,即::($pkg-arg),这是使用$pkg-arg作为字符串名称的符号查找.
结果是pkg-sym最终包含一个包符号名称(如果查找未能找到匹配的符号名称,则失败).
留下最后一行.这会在包pkg-sym中查找名为$subname的子:
my \sub-ref = &pkg-sym::($subname);
&需要确保RHS被视为参考,而不是试图调用例行程序.并且pkg-sym必须是一个无法识别的标识符,否则代码将无法工作.
在这三行代码的末尾,sub-ref包含Failure或对所需子的引用.