标识符术语在文档alongside constants中定义,具有几乎相同的用例,尽管术语在运行时计算其值,而常量在编译时获取。潜在地,这可能会使术语使用全局变量,但这是遥不可及的,因此我想这不是它们的用例。 OTOH,它们可能只是带有null签名的简单例程:
sub term:<þor> { "Is mighty" }
sub Þor { "Is mighty" }
say þor, Þor;
但是您已经可以使用空签名定义例程。但是,您可以编写以下错误:
say Þor ~ Þor;
produce a many positionals passed; expected 0 arguments but got 1
与术语不同。但是,这似乎有些牵强,您可以通过在末尾添加()来节省麻烦。
另一个可能的用例是defying the rules of normal identifiers
sub term:<✔> { True }
say ✔; # True
我还有其他用例吗?
答案 0 :(得分:5)
将零参数subs用作术语将打破后声明subs的可能性,因为在解析了subs的用法后找到sub会要求重新解析早期的代码(perl 6语言拒绝这样做,“一次解析”以及所有内容)(如果该子对象不带任何参数。
答案 1 :(得分:4)
术语与三元运算符结合使用非常有用:
match(as.Date("2019-01-02"), as.Date(timestamp))
答案 2 :(得分:3)
常量基本上是术语。因此,它们当然会组合在一起。
constant foo = 12;
say foo;
constant term:<bar> = 36;
say bar;
有一点区别,因为term:<…>
通过修改解析器起作用。因此优先。
constant fubar = 38;
constant term:<fubar> = 45;
say fubar; # 45
无论先定义哪个45
,以上内容都会打印constant
。
由于term:<…>
优先,获取其他值的唯一方法是使用::<fubar>
直接访问符号表。
say ::<fubar>; # 38
say ::<term:<fubar>>; # 45
term:<…>
有两个主要用例。
一种方法是使子例程的解析类似于常量或无符号变量。
sub fubar () { 'fubar'.comb.roll }
# say( fubar( prefix:<~>( 4 ) ) );
say fubar ~ 4; # ERROR
sub term:<fubar> () { 'fubar'.comb.roll }
# say( infix:<~>( fubar, 4 ) );
say fubar ~ 4;
另一种方法是使用常量或无sigi变量,而不是普通标识符。
my \✔ = True; # ERROR: Malformed my
my \term:<✔> = True;
say ✔;
当然,两个用例都可以组合。
sub term:<✔> () { True }
Perl 5允许子例程具有一个空的原型(不同于签名),这将改变其解析方式。 Perl 5中的原型的主要目的是改变代码的解析方式。
use v5;
sub fubar () { ord [split('','fubar')]->[rand 5] }
# say( fubar() + 4 );
say fubar + 4; # infix +
use v5;
sub fubar { ord [split('','fubar')]->[rand 5] }
# say( fubar( +4 ) );
say fubar + 4; # prefix +
Perl 6不像Perl 5使用原型那样使用签名。更改Perl 6解析代码的主要方法是使用名称空间。
use v6;
sub fubar ( $_ ) { .comb.roll }
sub term:<fubar> () { 'fubar'.comb.roll }
say fubar( 'zoo' ); # `z` or `o` (`o` is twice as likely)
say fubar; # `f` or `u` or `b` or `a` or `r`
sub prefix:<✔> ( $_ ) { "checked $_" }
say ✔ 'under the bed'; # checked under the bed
请注意,Perl 5实际上并没有常量,它们只是具有空原型的子例程。
use v5;
use constant foo => 12;
use v5;
sub foo () { 12 } # ditto
(在5.16之后,这种情况变得不那么真实了)
据我所知,原型的所有其他用途已被Perl6中的设计决定所取代。
use v5;
sub foo (&$) { $_[0]->($_[1]) }
say foo { 100 + $_[0] } 5; # 105;
由于sub
子例程的原型,该块被视为foo
lambda。
use v6;
# sub foo ( &f, $v ) { f $v }
sub foo { @_[0].( @_[1] ) }
say foo { 100 + @_[0] }, 5; # 105
在Perl 6中,如果期望一个术语,则将其视为lambda。因此,无需使用原型之类的功能来更改解析器。
即使您已经拥有涵盖该用例的功能,您仍要求将原型的一种用途重新带回。
这样做将是特例。 Perl 6的部分设计思想是限制特殊情况的数量。
其他版本的Perl具有多种特殊情况,要记住所有特殊情况并不总是那么容易。
别误会我的意思; Perl 5中的特殊情况很有用,但是Perl 6在大多数情况下使它们成为一般情况。