2014-11-20 116 views
2

我正在寻找一个相当不确定的question关于是否最好使用(;;)或while(1)当你想做一个无限循环,我看到一个有趣的解决方案,在C你可以#define“EVER”作为常数等于“;;”并从字面上循环for(EVER)为什么这不会永远运行?

我知道定义一个额外的常量来做这个可能不是最好的编程实践,但纯粹是为了教育目的,我想看看这是否也可以用Perl来完成。

我试图让Perl等效,但它只循环一次,然后退出循环。


#!/usr/bin/perl -w 

use strict; 
use constant EVER => ';;'; 

for (EVER) { 
    print "FOREVER!\n"; 
} 

输出:

FOREVER! 

为什么不这项工作在Perl?

回答

5

C的预处理器常量与大多数语言中的常量大不相同。

正常常数就像一个变量,只能设置一次;它有一个值可以在变量的大部分地方传递,从你和编译器的一些好处知道它不会改变。这是Perl's constant pragma为您提供的常数类型。当您将常数传递给for运算符时,它只会将其视为字符串值,并相应地运行。

但是,C有一个在编译器甚至看到代码之前运行的步骤,称为预处理器。这实际上是操纵你的源代码的文本,而不知道或关心它的大部分含义,所以可以做各种你不能在语言本身做的事情。在#DEFINE EVER ;;的情况下,您告诉预处理器用;;替换每个出现的EVER,以便当实际编译器运行时,它只能看到for(;;)。您可以更进一步,将forever这个词定义为for(;;),它仍然可以工作。

Andrew Medico在评论中提到,最接近Perl的预处理器是source filters,实际上手册中的一个示例是#define的仿真。这些实际上比预处理器宏更强大,允许人们编写像Acme :: Bleach这样的模块(在保留功能的同时用空白替换整个程序)和Lingua :: Romana :: Perligata(解释用语法正确的拉丁文编写的程序) ,以及更多明智的功能,例如为类和方法声明添加关键字和语法。

5

它不会永远运行,因为';;'是一个普通字符串,而不是预处理器宏(Perl没有C预处理器的等价物)。因此,for (';;')运行一次,$_设置为';;'那一次。

+0

啊,我明白了......这是否意味着无法在perl中模仿这种功能?在这一点上,我只是好奇,看看是否可以做到。 – tjwrona1992 2014-11-20 20:58:49

+2

您可以使用[源代码过滤器](http://perldoc.perl.org/perlfilter.html)将它们一起破解。 – 2014-11-20 20:59:56

+0

@ tjwrona1992你可以用字符串eval和变量插值来实现。例如。 ($ ever)''eval“...”'但是,为什么当你可以简单地使用while循环呢? '而(EVER)...' – TLP 2014-11-20 22:47:02

0

这在Perl中是不可能的。但是,您可以定义一个永远命名子这需要一个代码块作为参数,并一次又一次地运行它:

#!/usr/bin/perl 
use warnings; 
use strict; 

sub forever (&) { 
    $_[0]->() while 1 
} 

forever { 
    print scalar localtime, "\n"; 
    sleep 1; 
}; 
3

安德鲁医学生在他的评论中提到,你可以用source filter.

一起本事我证实了这一点,这里是一个例子。

use Filter::cpp; 
#define EVER ;; 
for (EVER) { 
    print "Forever!\n"; 
} 

输出:

Forever! 
Forever! 
Forever! 
... keeps going ... 

我不认为我会推荐这样做,但它是可能的。

相关问题