首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Perl提供了其他语言所没有的哪些编译时特性?

Perl提供了其他语言所没有的哪些编译时特性?
EN

Stack Overflow用户
提问于 2010-08-26 13:35:25
回答 3查看 450关注 0票数 4

被认为是一种通用的编程语言??

维基百科上读到

Perl有一个图灵完整的语法,因为在编译阶段执行的运行时代码可能会影响解析。41因此,Perl不能被一个直接的Lex/Yacc lexer/解析器组合解析。相反,解释器实现了自己的lexer,它与修改后的GNU解析器进行协调,以解决语言中的歧义。 人们常说“只有Perl才能解析perl”,这意味着只有Perl解释器( Perl )才能解析Perl语言(Perl),但通常情况下,这也不是真的。因为Perl解释器可以在编译阶段模拟图灵机,因此需要确定停止问题,以便在每种情况下都完成解析。这是一个长期的结果,停止问题是不可判定的,因此即使是Perl也不能总是解析perl。Perl做出了不同寻常的选择,让用户在自己的编译阶段访问它的全部编程能力。就理论纯度而言,成本很高,但实际不便似乎很少。

因此,它说,尽管Perl具有图灵完整标记,但它不同于其他语言,因为它允许“用户在自己的编译阶段访问它的全部编程能力”。这是什么意思?在编译阶段给我提供了哪些编程能力,而其他人却没有?

EN

回答 3

Stack Overflow用户

发布于 2010-08-26 13:44:38

Perl的任何特性都不会出现在任何其他语言中。Lisp可以做任何事情(这里的Lisp就是一个例子)。因此,也许我们可以将问题缩小到Perl的哪些特性,这些特性使行为大幅度波动成为一件容易的事情。

  • BEGIN块(也是端块)。这会改变编译期间的行为。因此,我可以编写Perl代码,以更改要加载的模块的位置。 甚至下面的代码也可能有不同的含义。 使用Frobnify;Frobnify->new->initialize; 因为我可以更改Frobnify从以下位置加载的位置: 开始{ if ( localtime ->6 == 2){s\x^/var\var/var/d数/星期二foreach @==;} 所以在星期二,我加载/var/days/tuesday/perl/lib/Frobnify.pm
  • 源滤波器可以以编程方式编辑将要执行的代码。(请注意源过滤器!)(大致相当于LISP宏)
  • BEGIN块一起使用的是钩子。因为我可以在开始时修改@INC,从而看到加载的内容发生了变化。我可以在@INC数组的前面设置一个子例程来加载我想要加载的任何东西。钩子可以接收加载Frobnify的请求,并通过加载Defrobnify.pm来响应它。
  • 在某种程度上,这是象征的狂热。在加载Defrobnify.pm之后,我可以这样做: *Frobnify::=: 现在Frobnify->new创建了一个Defrobnify对象!
票数 6
EN

Stack Overflow用户

发布于 2010-08-26 16:13:41

子例程原型是一个编译时特性,或多或少是Perl的专有特性。Perl的许多内置函数对它们的参数(标量、列表、引用、代码块、捕获)施加了特殊类型的上下文。原型是将部分功能移植到用户定义的子例程的一种方式。

例如,Perl允许您使用(&)原型有效地生成新的语法结构。这在尝试::微型这样的模块中被用来向语言中添加trycatch关键字:

代码语言:javascript
复制
    try {
            die "foo";
    } catch {
            warn "caught error: $_"; # not $@
    };

这是因为trycatch被声明为sub try (&;@) { ... }sub name {...}语法等价于BEGIN { *name = sub {...} },这意味着它具有编译时间的效果。在try的例子中,(&;@)原型告诉编译器,每当它看到标识符try时,第一个参数必须是一个裸块,在这个块后面是一个可选列表。

这只是原型的一个例子,它们能够做许多其他的事情:

代码语言:javascript
复制
$  imposes scalar context on an argument
&  imposes code context on an argument
@  imposes list context on an argument
%  imposes list context (with an even number of elements)
*  imposes glob context on the argument 
\$ imposes scalar reference context
\@ imposes array reference context
   ... for the rest of the sigils

由于它们的威力(以及在其他语言中不存在),原型可能会令人困惑,最好是适度使用。(就像Perl的其他高级特性一样)。

票数 4
EN

Stack Overflow用户

发布于 2010-08-26 13:51:08

简单的答案是,BEGIN块提供图灵完整性:

代码语言:javascript
复制
BEGIN {
    my $foo = turing_machine_simulator($program);
}

perl编译器一看到BEGIN块,就会立即执行它们。这意味着可以要求编译器执行任意复杂的任务。Perl所能做的任何事情,它都可以在编译阶段完成。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3575581

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档