我有一些类(需要更多的类)如下所示:
use Unit;
class Unit::Units::Ampere is Unit
{
method TWEAK { with self {
.si = True;
# m· kg· s· A ·K· mol· cd
.si-signature = [ 0, 0, 0, 1, 0, 0, 0 ];
.singular-name = "ampere";
.plural-name = "ampere";
.symbol = "A";
}}
sub postfix:<A> ($value) returns Unit::Units::Ampere is looser(&prefix:<->) is export(:short) {
return Unit::Units::Ampere.new( :$value );
};
sub postfix:<ampere> ($value) returns Unit::Units::Ampere is looser(&prefix:<->) is export(:long) {
$value\A;
};
}我希望能够在运行时动态地构造和导出自定义操作符。我知道如何使用导出,但是如何动态创建后缀操作符?
发布于 2017-11-09 12:51:17
我最后基本上做了这
sub EXPORT
{
return %(
"postfix:<A>" => sub is looser(&prefix:<->) {
#do something
}
);
}这是令人不安的简单。
发布于 2017-11-06 15:27:18
对于第一个问题,您可以通过从另一个问题返回一个subs来创建动态subs。若要仅接受Ampere参数(其中以编程方式选择"Ampere“),请在函数签名中使用类型捕获:
sub make-combiner(Any:U ::Type $, &combine-logic) {
return sub (Type $a, Type $b) {
return combine-logic($a, $b);
}
}
my &int-adder = make-combiner Int, {$^a + $^b};
say int-adder(1, 2);
my &list-adder = make-combiner List, {(|$^a, |$^b)};
say list-adder(<a b>, <c d>);
say list-adder(1, <c d>); # Constraint type check fails注意,当我定义内部sub时,我必须在sub关键字之后放一个空格,以免编译器认为我在调用一个名为"sub“的函数。(另一种方法请看我的答案的结尾。)
现在,关于困难的部分:如何导出这些生成的函数之一?is export真正所做工作的文档如下:导出
在页面的另一半,他们有一个例子,向符号表中添加一个函数,而不能在编译时编写is export。要使上面的工作正常进行,它需要位于一个单独的文件中。要查看以编程方式确定的名称和以编程方式确定的逻辑的示例,请创建以下MyModule.pm6:
unit module MyModule;
sub make-combiner(Any:U ::Type $, &combine-logic) {
anon sub combiner(Type $a, Type $b) {
return combine-logic($a, $b);
}
}
my Str $name = 'int';
my $type = Int;
my package EXPORT::DEFAULT {
OUR::{"&{$name}-eater"} := make-combiner $type, {$^a + $^b};
}调用Perl 6:
perl6 -I. -MMyModule -e "say int-eater(4, 3);"正如所希望的那样,输出为7。注意,在这个版本中,我使用了anon sub,它允许您命名生成的“匿名”函数。我知道这主要是用于生成更好的堆栈跟踪。
尽管如此,我在动态设置后缀操作符的优先级时遇到了问题。我认为您需要修改操作符的Precedence角色,或者自己创建它,而不是让编译器为您创建它。这没有记录在案。
https://stackoverflow.com/questions/47136106
复制相似问题