(标识符)术语与常数与无效签名例程



标识符项与常数一起在文档中定义,但使用案例几乎相同,尽管术语在运行时计算其价值,而常数则在编译时间内将其汇总。可能的是,这可能会使条款使用全球变量,但这是距离和丑陋的动作,所以我想那不是他们的用例。OTOH,它们可以简单地是带有空签名的例程:

sub term:<þor> { "Is mighty" }
sub Þor { "Is mighty" }
say þor, Þor;

,但是您已经可以用零签名定义例程。但是,您可以萨布(Sabe)编写时的错误:

say Þor ~ Þor;

将产生many positionals passed; expected 0 arguments but got 1,与该术语不同。但是,这似乎有点牵强,您可以通过在末尾添加()来节省麻烦。

另一个可能的用例是违反普通标识符的规则

sub term:<✔> { True }
say ✔; # True

我还有其他用例吗?

使零argument subs起作用,因为条款将破坏declare subs的可能性,因为在解析其用法后找到一个sub将需要重新审查早期代码(perl 6语言拒绝执行"一通解析"等等。

术语与三元运算符结合使用很有用:

$ perl6 -e 'sub a() { "foo" }; say 42 ?? a !! 666'
===SORRY!=== Error while compiling -e
Your !! was gobbled by the expression in the middle; please parenthesize
$ perl6 -e 'sub term:<a> { "foo" }; say 42 ?? a !! 666'
foo

常数基本上是术语。因此,当然它们被分组在一起。

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:<…>有两个主要用例。

一个是要使子例程与常数或sigilless变量类似。

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;

另一个是具有常规标识符以外的常数或sigiless变量。

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之后变得不那么真实)


据我所知,原型的所有其他用途已被Perl 6中的设计决策所取代。

use v5;
sub foo (&$) { $_[0]->($_[1]) }
say foo { 100 + $_[0] } 5; # 105;

由于foo子例程的原型。

,该块被视为sub 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在很大程度上使它们成为通用案例。

最新更新