2013-07-05 37 views
17

通常情況下,一個包開始只是作爲「標準」和塊封裝聲明有什麼不同嗎?

package Cat; 
... #content 
!0; 

我才發現,原來從perl的5.14開始有「塊」的語法了。

package Cat { 
    ... #content 
} 

它可能是相同的。但可以肯定的是,有沒有的區別?

而關於1;在包文件的末尾。任何塊的返回值都被視爲最後評估的表達式的值。那麼我可以在}之前把1;?爲了使require快樂,有什麼區別:

package Cat { 
    ... #content 
    1; 
} 

package Cat { 
    ... #content 
} 
1; 
+0

我只是建議,如果'require'無論哪種方式都很快樂(沒有差別),那麼就'require'而言沒有區別。你的意思是說通過自己嘗試代碼找到答案根本沒有幫助嗎? – doubleDown

+1

@Nemo'package NAME {...}'只是'{package NAME; ...}';他們是完全一樣的東西。如果文件中的最後一個語句是一個塊,那麼塊中的最後一個語句就是'require'將會得到的值。 – amon

+1

公平地說,你的問題沒有提到你自己嘗試過,沒有發現任何區別,所以我建議你也許可以嘗試它(第二部分)。既然你發現它是冒犯性的(儘管它不是我的意圖),我會刪除這個違規的評論。 – doubleDown

回答

11

當然是有區別的。第二個變體具有

A package聲明設置subs和全局變量的當前名稱空間。這是正常的範圍,即範圍以文件或eval字符串的結尾或封閉塊結束。

package NAME BLOCK語法是

{ package NAME; 
    ...; 
} 

只是語法糖甚至編譯下降到相同操作碼。

儘管package聲明在語法上是一種聲明,但這在語義上不是真的;它只是設置編譯時的屬性。因此,最後一個塊的最後一條語句是文件的最後一條語句,並且有

package Foo; 
1; 

package Foo { 
    1; 
} 

WRT沒有區別。最後的聲明。

package BLOCK語法很有趣,主要是因爲它看起來像其他語言的class Foo {},我認爲。因爲塊限制了範圍,所以這也使得正確使用範圍變量變得更容易。認爲:

package Foo; 
our $x = 1; 
package main; 
$::x = 42; 
say $x; 

輸出:1,因爲our是詞法範圍的像my,只是聲明瞭一個別名!這可以通過塊語法來阻止:

package Foo { 
    our $x = 1; 
} 
package main { 
    $::x = 42; 
    say $x; 
} 

按預期工作(42),雖然strict不開心。

3

差異:)如果你可以嘗試以下運行兩個不同的代碼段(只是導入模塊一個perl文件)

# perlscript.pl 

use wblock; 

wblock::wbmethod(); 

第一個代碼段,而不塊,wblock.pm

package wblock1; 
my $a =10; 
sub wbmethod1{ 
     print "in wb $a"; 
} 

package wblock; 

sub wbmethod{ 
     print "in wb1 $a"; 
} 
1; 

第二,wblock.pm

package wblock1 { 
my $a =10; 
sub wbmethod1{ 
     print "in wb $a"; 
} 
1; 
} 

package wblock { 
sub wbmethod{ 
     print "in wb1 $a"; 
} 
1; 
} 

現在,你可能已經看到不同的是,可變$a不適用於wblock包當我們使用BLOCK。但是,如果沒有BLOCK,我們可以使用其他包中的$a,因爲它的範圍是文件。

更多從自身perldoc說:

也就是說,沒有一個BLOCK的形式是通過手術的 結束當前的範圍,就像我的,狀態和我們的運營商。

+0

你的意思是:「如果你有多個沒有BLOCK的軟件包,你不能單獨使用1;每個軟件包都會單獨使用,你會得到錯誤的。」?你能發佈導致錯誤的代碼示例嗎?我試過了,它似乎工作正常。 – doubleDown

+0

@doubleDown - 我認爲你是對的。刪除相同。 – 2013-07-05 12:24:49

+4

'1;'被添加到'* .pm'文件的末尾,以向Perl編譯器指示該文件已正確加載。它與包無關。因此,應該只有一個'1;',它應該在文件的末尾。 – shawnhcorey

5
package Foo { ... } 

相當於

{ package Foo; ... } 

這是從它創建一個塊

package Foo; ... 

這隻事項如果你有文件在下面的代碼如下不同。


package Foo { ... } 

相當於

BEGIN { package Foo; ... } 

我會喜歡這一點,但這一建議未被接受。


require(和do)要求在文件中最後計算的表達式返回一個真值。 { ... }計算結果爲內評估的最後的值,所以下面是罰款:

package Foo { ...; 1 } 

在外面放置1;更有意義,我—它涉及到的文件,而不是包—但是這僅僅是一個風格的選擇。

1

只有在您正在進行難以維護的編程時,纔會有區別。特別是,如果您在軟件包中使用my變量。 Perl的慣例是每個文件只有一個包,而整個包只有一個文件。

1

還有一個其他的區別,其他答案沒有給出,這可能有助於解釋爲什麼有兩個。

package Foo; 
sub bar { ... } 

始終是在Perl 5中完成它的方式。package BLOCK語法

package Foo { 
    sub bar { ... } 
} 

僅在perl 5.14處添加。

主要區別在於後者的形式較整潔,但只能在5.14以後才能使用;前一種形式將回到舊版本。整潔的形式主要用於視覺上的整潔;它沒有任何值得擔心的語​​義差異。

相關問題