2014-11-20 110 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 ... 

我不認爲我會推薦這樣做,但它是可能的。

相關問題