內容

名稱

perl5240delta - perl v5.24.0 的新增功能

說明

此文件說明 5.22.0 版本和 5.24.0 版本之間的差異。

核心強化功能

後綴式解參考不再是實驗性質

使用 postderefpostderef_qq 功能不再會產生警告。先前停用 experimental::postderef 警告類別的現有程式碼將會繼續運作。postderef 功能沒有作用;所有 Perl 程式碼都可以使用後綴式解參考,不論範圍內有哪些功能宣告。5.24 功能套件現在包含 postderef_qq 功能。

現在支援 Unicode 8.0

有關此版本內容的詳細資訊,請參閱 http://www.unicode.org/versions/Unicode8.0.0/

perl 現在會在無法關閉就地輸出檔案時發出 croak 訊息

到目前為止,系統並未偵測到無法關閉就地編輯的輸出檔案,這表示輸入檔案可能會在編輯未成功完成的情況下遭到破壞。現在,如果無法成功關閉輸出檔案,系統會引發例外狀況。

正規表示式中的新 \b{lb} 界線

lb 代表換行符號。這是一個 Unicode 屬性,用於判斷文字列在哪裡適合換行(通常是為了讓文字列輸出時不會超出可用的水平空間)。Unicode::LineBreak 模組很早就提供這個功能,但現在核心 Perl 中有一個輕量級、不可自訂的版本,適用於許多目的。

qr/(?[ ])/ 現在可以在 UTF-8 地區設定中運作

延伸方括號字元類別現在會在 use locale 生效時成功編譯。編譯後的模式會使用標準 Unicode 規則。如果執行時期的地區設定不是 UTF-8,系統會引發警告,並仍使用標準 Unicode 規則。由於結果實際上並不依賴於地區設定,因此不會發生污染。

整數位移 (<<>>) 現在有更明確的定義

負位移是反向位移:左位移變為右位移,而右位移變為左位移。

以原生整數中的位元數(或更多)進行位移為零,但當「過度位移」在「使用整數」下右位移負值時除外,這種情況下結果為 -1(算術位移)。

到目前為止,負位移和過度位移尚未定義,因為它們依賴於 C 實作所執行的任何操作。例如,對於過度位移,常見的 C 行為是「模數位移」

1 >> 64 == 1 >> (64 % 64) == 1 >> 0 == 1  # Common C behavior.

# And the same for <<, while Perl now produces 0 for both.

現在,這些行為在 Perl 中已明確定義,無論底層 C 實作如何。但是,請注意,您仍然受到原生整數寬度的限制:您需要知道可以向左移動多遠。例如,您可以使用

use Config;
my $wordbits = $Config{uvsize} * 8;  # Or $Config{uvsize} << 3.

如果您需要在左位移上使用更多位元,則可以使用例如 bigint pragma 或 CPAN 中的 Bit::Vector 模組。

printf 和 sprintf 現在允許重新排序精確度引數

也就是說,sprintf '|%.*2$d|', 2, 3 現在傳回 |002|。這擴充了現有的重新排序機制(允許對用作格式欄位、寬度和向量分隔符的引數重新排序)。

使用 SA_SIGINFO 提供給 sigaction 回呼的更多欄位

SA_SIGINFO 旗標傳遞給 sigaction 時,errnostatusuidpidaddrband 欄位現在包含在傳遞給處理常式的雜湊中(如果平台支援的話)。

Hashbang 重定向至 Perl 6

以前,perl 會將雜湊符號路徑重新導向到另一個直譯器,除非路徑包含「perl」(請參閱 perlrun)。為了改善與 Perl 6 的相容性,此行為已延伸到「perl」後面接著「6」時也會重新導向。

安全性

在呼叫 mkstemp(3) 之前設定適當的 umask

在 5.22 中,perl 開始在呼叫 mkstemp(3) 之前將 umask 設定為 0600,然後再將其還原。這錯誤地告訴 open(2) 在套用給定的模式之前,從該模式中移除所有者讀取和寫入位元,而不是預期的僅保留這些位元的否定。

mkstemp(3) 中使用模式 0666 的系統(例如舊版本的 glibc)會建立一個權限為 0066 的檔案,讓世界讀取和寫入權限不受當前 umask 影響。

這已透過改用 umask 0177 修復。[perl #127322]

修復 Win32 路徑處理中的超出界線存取

這是 CVE-2015-8608。如需更多資訊,請參閱 [GH #15067]

修復 canonpath 中的 taint 遺失

這是 CVE-2015-8607。如需更多資訊,請參閱 [GH #15084]

避免在 win32 crypt() 中存取未初始化的記憶體

新增驗證,將偵測到 salt 中的短 salt 和無效字元。 [GH #15091]

environ 中移除重複的環境變數

先前,如果環境變數在 environ[] 中出現超過一次,%ENV 會包含該名稱的最後一個項目,而典型的 getenv() 會傳回第一個項目。我們現在確保 %ENV 包含與 getenv 傳回相同的內容。

其次,我們從 environ[] 中移除重複項目,因此如果在 %ENV 中設定具有該名稱的設定,我們不會傳遞不安全的數值給子程序。

[CVE-2016-2381]

不兼容變更

autoderef 功能已移除

實驗性的 autoderef 功能(允許在標量引數上呼叫 pushpopshiftunshiftsplicekeysvalueseach)已被視為不成功。它現已移除;嘗試使用該功能(或停用它先前觸發的 experimental::autoderef 警告)現在會產生例外狀況。

詞彙 $_ 已移除

my $_ 在 Perl 5.10 中引入,隨後造成許多混淆,沒有明顯的解決方案。在 Perl 5.18.0 中,它被設定為實驗性的,理論上它將會被移除或以較不混淆(但向後不兼容)的方式重新設計。在接下來的幾年中,沒有提出任何替代方案。該功能現已移除,且無法編譯。

qr/\b{wb}/ 現在已根據 Perl 期望進行調整

這現在更適合作為純粹 \b 的插入替換,但對於解析自然語言有更好的結果。先前,它嚴格遵循目前的 Unicode 規則,要求它與每個空白字元相符。現在,它通常不與空白範圍內相符,行為就像 \b 一樣。請參閱 perlrebackslash 中的「\b{wb}」

正規表示式編譯錯誤

一些在執行階段發生錯誤的正規表示式模式現在根本無法編譯。

現在,使用 \p{}\P{} 正規表示式模式建構的所有 Unicode 屬性幾乎都在模式編譯階段檢查其有效性,而無效的屬性將導致程式無法編譯。在早期版本中,此檢查通常會延後到執行階段。每當錯誤檢查從執行階段移至編譯階段時,錯誤程式碼就會 100% 被捕獲,而之前只有在實際執行有問題的部分時才會被捕獲,對於無法到達的程式碼來說,可能永遠不會被捕獲。

現在在 use re "strict" 下不允許使用 qr/\N{}/

一個空的 \N{} 沒有意義,但為了向後相容性,它被接受為不執行任何操作,儘管預設會提出不建議使用的警告。但現在,這在 re 中的實驗性功能「「嚴格」模式」下是一個致命錯誤。

嵌套宣告現已禁止

myourstate 宣告不再允許在其他 myourstate 宣告內部。

例如,以下現已為致命錯誤

my ($x, my($y));
our (my $x);

[GH #14799]

[GH #13548]

/\C/ 字元類別已移除。

此正規表示式字元類別已在 v5.20.0 中標示為不建議使用,並自 v5.22.0 起產生不建議使用警告。它現在是編譯時期錯誤。如果您需要檢查組成 UTF8 編碼字元的個別位元組,請先對字串(或副本)使用 utf8::encode()

chdir('') 不再 chdirs home

自 perl v5.8 起,使用 chdir('')chdir(undef) 來 chdir home 已標示為不建議使用,現在將會失敗。請改用 chdir()

變數名稱中的 ASCII 字元現在必須全部可見

在 ASCII 平台上,變數名稱包含非圖形 ASCII 控制字元(序數 0 到 31,以及 127,也就是 C0 控制字元和 DELETE)一直是合法的。此用法已於 v5.20 版中棄用,而且現在會導致語法錯誤。這些名稱所指的變數很特別,Perl 保留這些變數,供其現在或未來使用。每個此類變數都有另一種拼寫方式。除了單一非圖形控制字元之外,還會使用以插入符號開頭的兩個字元序列,例如 $^]${^GLOBAL_PHASE}。詳情請參閱 perlvar。在未使用 use utf8 的情況下,在變數名稱中使用某些非圖形非 ASCII 字元仍然合法,但不明智且已棄用(會產生棄用警告)。不應有任何程式碼執行此操作,因為所有此類變數都已由 Perl 保留,而且 Perl 目前並未定義任何變數(但可能隨時在未通知的情況下定義)。

已修正 $Carp::MaxArgNums 中的 off by one 問題

$Carp::MaxArgNums 應為要顯示的引數數量。在此版本之前,它會顯示 $Carp::MaxArgNums + 1 個引數,這與文件說明不符。

現在僅允許在 (?[...]) 內的 [...] 內使用空白和 tab。

實驗性的擴充方括號字元類別可以在其中包含常規方括號字元類別。它們與常規類別的不同之處在於,通常會忽略空白,除非在空白前面加上反斜線作為跳脫字元。現在,被忽略的空白僅限於 tab \t 和 SPACE 字元。以前,它會忽略任何空白。請參閱 "perlrecharclass 中的「擴充方括號字元類別」"

不建議使用的功能

現在不建議使用平台 IV_MAX 以上的代碼點

Unicode 定義範圍在 0..0x10FFFF 中的代碼點。某些標準曾經將它們定義為最高 2**31 - 1,但 Perl 允許它們高到與所使用平台上的字元一樣高。但是,在某些結構中,使用平台 IV_MAX 以上的代碼點會中斷,特別是 tr///、涉及量詞的正規表示式模式,以及某些算術和比較運算,例如作為迴圈的上限。現在,使用此類代碼點會產生不建議使用的功能警告,除非關閉該警告類別。在 32 位元平台上,IV_MAX 通常為 2**31 -1,在 64 位元平台上則為 2**63-1。

不建議對包含 0xFF 以上代碼點的字串執行位元運算

字串位元運算子將其運算元視為位元組字串,而在此上下文中,0xFF 以上的值沒有意義。若要對編碼位元組執行運算,請先對字串進行編碼。若要對代碼點的數值執行運算,請使用 splitmap ord。未來,此警告將被例外狀況取代。

不建議在 :utf8 處理中使用 sysread()syswrite()recv()send()

在明確或隱含具有 :utf8 層的句柄上,sysread()recv()syswrite()send() 算子已棄用,例如,使用 :encoding(UTF-16LE) 層。

目前 sysread()recv() 都只使用串流的 :utf8 標記,忽略實際的層。由於 sysread()recv() 沒有進行 UTF-8 驗證,因此可能會產生編碼無效的純量。

類似地,syswrite()send() 也只使用 :utf8 標記,否則會忽略任何層。如果設定標記,則兩者都會寫入 UTF-8 編碼的值,即使該層是其他編碼,例如上述範例。

理想情況下,所有這些算子都應該完全忽略 :utf8 狀態,只使用位元組,但這會導致靜默中斷現有程式碼。為避免這種情況,未來版本的 perl 將在 sysread()recv()syswrite()send() 在具有 :utf8 層的句柄上呼叫時擲回例外。

效能強化

模組和實用程式

已更新的模組和實用程式

文件

現有文件變更

perlapi

perlcall

perlfunc

perlguts

perllocale

perlmodlib

perlop

perlpolicy

perlreftut

perlrebackslash

perlsub

perlsyn

perltie

perlunicode

perlvar

perlxs

診斷

已對診斷輸出(包括警告和致命錯誤訊息)進行下列新增或變更。如需完整的診斷訊息清單,請參閱 perldiag

新增診斷

新增錯誤

新增警告

現有診斷變更

組態和編譯

測試

平台支援

特定平台注意事項

AmigaOS
  • AmigaOS 埠已重新整合到主程式碼樹,根據 Perl 5.22.1。

Cygwin
  • 測試對異常的 cygdrive 前置字元更強健。 [GH #15076]

EBCDIC
UTF-EBCDIC 延伸

UTF-EBCDIC 類似於 UTF-8,但適用於 EBCDIC 平台。現在已延伸,因此可以在 64 位元字元的平台上表示高達 2 ** 64 - 1 的碼點。這使其與 UTF-8 相等。此增強功能需要對 2 ** 30 至 2 ** 31 -1 範圍內碼點的表示方式進行不相容的變更 (後者是先前可表示的最大碼點)。這表示使用先前版本 perl 寫出的、包含其中一個碼點的檔案,無法在不轉換的情況下,由包含此變更的 perl 讀取。我們不認為有此類檔案存在,但如果您有,請提交票證至 perlbug@perl.org,我們會為您撰寫轉換指令碼。

已修正 cmp()sort(),適用於 UTF-EBCDIC 字串

比較兩個編碼為 UTF-8 (或更精確地說,UTF-EBCDIC) 的字串,直到現在都無法正常運作。由於 sort() 使用 cmp(),這也修正了這個問題。

已修正 tr///y///,適用於 \N{}use utf8 範圍

Perl v5.22 引入了可攜式範圍的概念,適用於正規表示式模式。不論在什麼平台上執行,可攜式範圍都會比對同一組字元。這個概念現在延伸到 tr///。請參閱 tr///

use utf8 下,這些運算也有一些問題,現在已修正

FreeBSD
  • 如果可以使用,請使用 FreeBSD 的 fdclose() 函式。 [GH #15082]

IRIX
  • 在某些情況下,IRIX stdio fgetc()fread() 會將 errno 設定為 ENOENT,這根據 IRIX 或 POSIX 文件都沒有道理。在這種情況下,現在會清除 Errno。 [GH #14557]

  • 已修正將長雙精度乘以無限大時出現的問題。 [GH #14993]

MacOS X
  • 到目前為止,perl 的 OS X 建置已指定 10.3(Panther,2003)的連結目標,但未指定編譯器目標。從現在開始,在 OS X 10.6 或更新版本(Snow Leopard,2008)上建置 perl 時,預設會擷取目前的 OS X 版本,並在編譯器和連結器旗標中將其指定為明確的建置目標,從而保留二進位相容性,以便在 OS X、SDK 或編譯器和連結器版本變更後,仍可建置擴充功能。若要覆寫建置中使用的預設值並保留在旗標中,請在設定和建置 perl 之前指定 export MACOSX_DEPLOYMENT_TARGET=10.N,其中 10.N 是您希望鎖定的 OS X 版本。在 OS X 10.5 或更早版本中,當這些系統為目前版本時,行為並無變更;連結目標仍為 OS X 10.3,且沒有明確的編譯器目標。

  • 在 OS X 上從 Terminal 建置或測試時,同時啟用 -DDEBUGGING 和執行緒的建置會因「恐慌:從錯誤的池中釋放」錯誤而失敗。這是因為 perl 內部管理的環境與使用 libc setenv() 函數更新環境的 atfork 處理常式發生衝突所致。

    Perl 現在使用 setenv()/unsetenv() 來更新 OS X 上的環境。 [GH #14955]

Solaris
  • 所有 Solaris 變體現在都會建置共用 libperl

    Solaris 和 OpenIndiana 等變體現在總是使用共用 Perl 函式庫建置(Configure -Duseshrplib)。OpenIndiana 建置需要這樣做,但這也是 Oracle/Sun Perl 建置好幾年的設定。

Tru64
  • 當原型列為 PERL_STATIC_INLINE,但測試使用 -DPERL_NO_INLINE_FUNCTIONS 建置時,解決 Tru64 會出錯的問題。

VMS
  • 在 VMS 上,math.h 中的數學函式原型現在可以在 C++ 中顯示。現在使用 C++ 建置 POSIX 擴充套件將不再會當機。

  • VMS 自 v7.0(於 1996 年發布)以來就有 setenv/unsetenvPerl_vmssetenv 現在總是使用 setenv/unsetenv

  • Perl 現在透過掃描指定處理程序群組中的處理程序來實作自己的 killpg,這可能與 Unix 處理程序群組不太相同,但允許我們將訊號傳送給父處理程序(或主處理程序)及其所有子處理程序。在 perl 層級,這表示我們現在可以傳送負面 pid,如下所示

    kill SIGKILL, -$pid;

    傳送訊號給與 $pid 相同群組中的所有處理程序。

  • 對於那些基於 CRTL 環境陣列的 %ENV 元素,我們在設定時始終保留大小寫,但僅在先將金鑰轉換為大寫後才進行查詢,這會導致遺失小寫或混合大小寫的項目。此問題已透過讓源自環境陣列的 %ENV 元素在查詢時區分大小寫,以及在儲存時保留大小寫來修正。

  • PERL5LIBPERLLIB 的環境查詢以前僅考慮邏輯名稱,但現在會考慮 %ENV 的所有來源,如 PERL_ENV_TABLES 所決定,並如 perlvms 中的「%ENV」 所述。

  • 現在支援的 VMS 最低版本為 2003 年發行的 v7.3-2。此變更的副作用是,VAX 不再受支援,因為 OpenVMS VAX 的終端版本為 2001 年的 v7.3。

Win32
  • 已將新的建置選項 USE_NO_REGISTRY 新增至 makefile。此選項預設為關閉,表示預設為執行 Windows 註冊表查詢。此選項可阻止 Perl 在註冊表中尋找任何內容。有關註冊表中查詢的值,請參閱 perlwin32。在 C 中,此選項的內部名稱為 WIN32_NO_REGISTRY

  • Perl 使用 HKEY_CURRENT_USER\Software\PerlHKEY_LOCAL_MACHINE\Software\Perl 來查詢特定值(包括以 PERL 開頭的 %ENV 變數)的行為已變更。以前,即使這兩個金鑰不存在,也會在 Perl 程序的整個生命週期中持續檢查是否有項目。基於效能考量,現在如果根金鑰(即 HKEY_CURRENT_USER\Software\PerlHKEY_LOCAL_MACHINE\Software\Perl)在程序啟動時不存在,則在 Perl 程序生命週期的剩餘時間內,將不會再次檢查是否有 %ENV 覆寫項目。這更接近 Unix 行為,因為環境會在啟動時複製或繼承,而且在父程序或其他程序中變更變數,或編輯 .bashrc,不會變更其他現有正在執行程序中的環境變數。

  • 已移除每個 -Xstat 呼叫的 glob 擷取,無論是從 Perl 程式碼或 Perl 的 C 程式碼內部執行。查詢的 glob 是特殊變數 ${^WIN32_SLOPPY_STAT}。這使得 -Xstat 稍微快一點。

  • 在 miniperl 的處理程序啟動期間,在建置處理程序期間,4 至 8 個與處理程序啟動 .plbuildcustomize.pl 檔案相關的 IO 呼叫已從開啟和執行第一個或第二個 .pl 檔案的程式碼中移除。

  • 使用 Microsoft Visual C++ 2003 及更早版本建置不再產生「內部編譯器錯誤」訊息。[perl #126045]

  • Visual C++ 2013 建置現在會在 XP 及更高版本執行。先前它們只會在 Vista 及更高版本執行。

  • 現在您可以使用 GNU Make 和 GCC 建置 perl。[perl #123440]

  • truncate($filename, $size) 現在適用於超過 4GB 大小的檔案。[perl #125347]

  • 已將平行建置新增到 dmake makefile.mk makefile。支援所有 Win32 編譯器。

  • 使用 64 位元 GCC 但使用 32 位元 gmake 建置 64 位元 perl 會導致結果 perl 的 $Config{archname} 無效。[perl #127584]

  • Winsock 函數設定的錯誤現在會直接放入 $^E,而相關的 WSAE* 錯誤碼現在會從 ErrnoPOSIX 模組匯出,以供測試。

    先前將錯誤(自 Perl 5.20.0 起轉換為 POSIX 格式的 E* 錯誤碼)放入 $! 的行為有錯誤,原因是 Winsock 和 POSIX 錯誤常數同名但不同等,而這兩者之間的關係自 Perl 5.8.0 起不幸地以某種方式建立。

    新的行為提供了一個更強大的解決方案,用於在可攜式軟體中檢查 Winsock 錯誤,而不會意外比對預計用於其他作業系統的 POSIX 測試,且可能對 Winsock 有不同的意義。

    目前舊有行為仍保留,包含所有缺點,以維持向後相容性,但建議使用者變更任何測試 $!E* 常數對應 Winsock 錯誤的程式碼,改為測試 $^EWSAE* 常數。在適當的淘汰期間後,舊有行為可能會移除,讓 $! 在 Winsock 函式呼叫後保持不變,以避免在檢查哪個錯誤變數時產生任何可能的混淆。

ppc64el
浮點數

ppc64el(Debian 為小端序 PowerPC 所取的名稱)的浮點數格式現在可以正確偵測。

內部變更

已選取的錯誤修正

致謝

Perl 5.24.0 代表自 Perl 5.24.0 以來約 11 個月的開發時間,並包含來自 75 位作者、橫跨 1,800 個檔案的約 360,000 行變更。

不包含自動產生的檔案、文件和發行工具,約有 250,000 行變更至 1,200 個 .pm、.t、.c 和 .h 檔案。

Perl 持續在第三個十年蓬勃發展,這要歸功於使用者和開發人員的活躍社群。已知以下人員貢獻了成為 Perl 5.24.0 的改進

Aaron Crane、Aaron Priven、Abigail、Achim Gratz、Alexander D'Archangel、Alex Vandiver、Andreas König、Andy Broad、Andy Dougherty、Aristotle Pagaltzis、Chase Whitener、Chas. Owens、Chris 'BinGOs' Williams、Craig A. Berry、Dagfinn Ilmari Mannsåker、Dan Collins、Daniel Dragan、David Golden、David Mitchell、Doug Bell、Dr.Ruud、Ed Avis、Ed J、Father Chrysostomos、Herbert Breunung、H.Merijn Brand、Hugo van der Sanden、Ivan Pozdeev、James E Keenan、Jan Dubois、Jarkko Hietaniemi、Jerry D. Hedden、Jim Cromie、John Peacock、John SJ Anderson、Karen Etheridge、Karl Williamson、kmx、Leon Timmermans、Ludovic E. R. Tolhurst-Cleaver、Lukas Mai、Martijn Lievaart、Matthew Horsfall、Mattia Barbon、Max Maischein、Mohammed El-Afifi、Nicholas Clark、Nicolas R.、Niko Tyni、Peter John Acklam、Peter Martini、Peter Rabbitson、Pip Cet、Rafael Garcia-Suarez、Reini Urban、Ricardo Signes、Sawyer X、Shlomi Fish、Sisyphus、Stanislaw Pusep、Steffen Müller、Stevan Little、Steve Hay、Sullivan Beck、Thomas Sibley、Todd Rinaldo、Tom Hukins、Tony Cook、Unicode Consortium、Victor Adam、Vincent Pit、Vladimir Timofeev、Yves Orton、Zachary Storer、Zefram。

以上清單幾乎肯定不完整,因為它是自動從版本控制記錄中產生的。特別是,它不包括向 Perl 錯誤追蹤器回報問題的(非常感謝的)貢獻者的姓名。

此版本中包含的許多變更源自於 Perl 核心所包含的 CPAN 模組。我們感謝整個 CPAN 社群協助 Perl 蓬勃發展。

如需取得 Perl 所有歷史貢獻者的更完整清單,請參閱 Perl 原始程式碼散佈中的 AUTHORS 檔案。

回報錯誤

如果您發現您認為是錯誤的問題,您可以查看最近張貼到 comp.lang.perl.misc 新聞群組的文章和 https://rt.perl.org/ 上的 perl 錯誤資料庫。Perl 主頁 http://www.perl.org/ 上也可能有相關資訊。

如果您認為您發現一個未回報的錯誤,請執行您的發行版本附帶的 perlbug 程式。務必將您的錯誤簡化為一個小巧但足夠的測試案例。您的錯誤回報,連同 perl -V 的輸出,將會傳送至 perlbug@perl.org,供 Perl 移植團隊分析。

如果您回報的錯誤有安全性影響,不適合傳送至公開封存的郵件清單,請參閱 "perlsec 中的安全性漏洞聯絡資訊",以取得如何回報問題的詳細資訊。

另請參閱

Changes 檔案,說明如何檢視已變更內容的詳盡詳細資料。

INSTALL 檔案,說明如何建置 Perl。

README 檔案,說明一般事項。

ArtisticCopying 檔案,說明著作權資訊。