目錄

名稱

perl5380delta - Perl v5.38.0 的新功能

描述

本文件描述了 5.36.0 版本與 5.38.0 版本之間的差異。

核心增強

class 功能

現在可以使用新的實驗性語法來定義物件類別,其中每個實例的數據存儲在「field」變數中,其行為類似於語彙範疇。

use feature 'class';

class Point
{
    field $x;
    field $y;

    method zero { $x = $y = 0; }
}

更多詳細信息請參閱perlclass。其實現的內部細節和其他相關細節可在perlclassguts中找到。

這仍然是一個新的實驗性功能,仍在積極開發中。它將成為未來版本中的更多添加、改進和變更的主題。由於它是實驗性的,因此在experimental::class類別中會產生警告。可以通過no warnings語句消除這些警告。

use feature 'class';
no warnings 'experimental::class';

支援 Unicode 15.0

詳情請參見https://www.unicode.org/versions/Unicode15.0.0/

棄用警告現在具有特定的子類別

所有棄用警告現在都有自己特定的棄用類別,可以單獨禁用。您可以在perldeprecationwarnings中查看所有棄用功能的列表。以下列表來自warnings

+- deprecated ----+
|                 |
|                 +- deprecated::apostrophe_as_package_separator
|                 |
|                 +- deprecated::delimiter_will_be_paired
|                 |
|                 +- deprecated::dot_in_inc
|                 |
|                 +- deprecated::goto_construct
|                 |
|                 +- deprecated::smartmatch
|                 |
|                 +- deprecated::unicode_property_name
|                 |
|                 +- deprecated::version_downgrade

仍然可以使用一條語句禁用所有棄用警告

no warnings 'deprecated';

但現在可以更細緻地控制。 歷史上一直如此,這些警告會自動啟用

use warnings;

%{^HOOK} API被引入

因為各種原因,對於某些Perl關鍵字創建子程序包裹可能會很困難。 任何具有未定義原型的關鍵字都無法用子程序包裹,而一些Perl允許包裹的關鍵字在實踐中非常棘手。 例如require是很棘手的,雖然可能,但這樣做會改變堆棧深度,並且標準的導出方法假定它們將導出到特定堆棧深度的包裹,否則封裝將改變函數導出到的位置,除非實施得非常小心,否則這可能非常棘手。

因此,我們引入了一個名為%{^HOOK}的新哈希,旨在促進這種情況。 當關鍵字支持任何類型的特殊鉤子時,鉤子將存在於這個新哈希中。 這個哈希中的鉤子將以調用它們的函數命名,然後是兩個下劃線,然後是它們被執行的階段,目前只有在關鍵字執行之前或之後。

在這個初始版本中,我們支持兩個鉤子require__beforerequire__after。 這些用於在require語句之前和之後執行任務,以使其更容易。

更多詳細信息請參見perlvar

PERL_RAND_SEED

新增了一個新的環境變量PERL_RAND_SEED,可以用來使使用rand但未明確使用srand()的Perl程序或者使用無參數的srand()的程序可以重複運行。參見perlrun。此功能可以在編譯時通過傳遞

-Accflags=-DNO_PERL_RAND_SEED

給編譯過程中的Configure來禁用。

在簽名中定義的或邏輯或分配默認表達式

現在,可以使用//=||=運算符來分配子程序簽名參數的默認表達式,以便在調用者提供未定義或false值(分別)時應用默認值,而不僅僅是在參數完全缺失時。有關更多詳細信息,請參見perlsub中的文檔。

@INC鉤子增強和$INC和INCDIR

已經加固了@INC鉤子的內部,以處理各種邊界情況,當鉤子在require操作期間修改@INC時,不再會出現段錯誤或斷言失敗。作為此操作的一部分,我們現在確保在一次require調用期間最多執行一次任何給定的鉤子,並且任何重複的目錄不會觸發額外的目錄探測。

為了提供開發者對動態模組查找更多控制權,現在支援一個名為INCDIR的新鉤子方法。支援此方法的物件可以被注入到@INC陣列中,當在模組搜索過程中遇到時,它將被執行,就像執行INC鉤子一樣,並將其返回值用作要搜索模組的目錄列表。返回一個空列表相當於沒有操作。請注意,由於此鉤子返回的任何參考都將被轉換為字符串並用作字符串,您不能通過此API返回稍後執行的鉤子。

當在require期間調用@INC鉤子(INCINCDIR之一)時,$INC變數將被局部化為鉤子來自的@INC的索引值。如果鉤子希望覆蓋@INC中的“下一個”索引應該是什麼,它可以將$INC更新為比所需索引少一的值(undef等同於-1)。這允許@INC鉤子完全重寫@INC陣列並使perl從@INC的開始重新啟動其目錄探測。

@INC中的已祝福CODE參考不再觸發異常,而是將與未祝福的coderef一樣對待,並且像它們是INC鉤子一樣執行。

現在在編譯時檢測到deferfinally中的控制流程被禁止

嘗試通過諸如returngoto之類的控制流程離開deferfinally塊是被禁止的。之前的perl版本只能在實際運行時檢測到這一點。

這個perl版本為許多可以在靜態上確定的情況添加了編譯時檢測。這可能意味著在先前版本的perl上成功編譯的代碼現在在此版本上被報告為編譯時錯誤。這只在實際執行代碼時會是一個錯誤的情況下才發生;錯誤只是在較早的時間發生。

模式中的樂觀評估

在模式中使用(?{ ... })(??{ ... })會全域地停用各種最佳化。這可能是程式設計者所期望的,也可能不是。此版本新增了(*{ ... })的等效方式。唯一的差異在於它不會且永遠不會停用正規表達式引擎中的任何最佳化。這可能使其在未來被呼叫的次數更多或更少,但它執行的次數將完全符合正規表達式引擎的功能。例如,當模式中包含(?{ ... })時,某些類型的最佳化會被停用,使得在正常使用時為O(N)的模式變為包含(?{ ... })模式時為O(N*N)。切換到(*{ ... })意味著模式將保持O(N)。

REG_INF已從65,536提高到2,147,483,647

過去許多正規表達式量詞的限制為U16_MAX,但現在限制為I32_MAX,因此現在可以寫/(?:word){1000000}/。請注意,這樣做可能會導致正規表達式引擎運行時間較長並使用更多記憶體。

New API函數optimize_optree和finalize_optree

有兩個新的API函數可用於操作optree片段,確保您可以調用可能否則不會被調用的optree生成過程的所需部分(例如,當創建自定義LOGOP時)。要訪問這些函數,您首先需要將一個#define設置為允許使用這些函數。

#define PERL_USE_VOLATILE_API

這些函數與解釋器內部的運作方式密切相關,如果其他內部更改需要,它們可能隨時會被修改或移除。

一些goto現在允許在deferfinally區塊中

Perl版本5.36.0新增了defer區塊並允許finally關鍵字也添加類似於try/catch語法的行為。這些並不允許區塊內部有任何goto表達式,因為這可能導致控制流跳出區塊。現在,如果它們具有常數目標標籤並且該標籤位於區塊內,則允許一些goto表達式。

use feature 'defer';

defer {
  goto LABEL;
  print "This does not execute\n";
  LABEL: print "This does\n";
}

新的正規表達式變數${^LAST_SUCCESSFUL_PATTERN}

這允許訪問在當前作用域中匹配的最後一個成功模式。正則表達式引擎的許多方面都涉及到“最後一個成功的模式”。空模式重複使用它,所有魔法正則表達式變量都與它相關。這允許訪問它的模式。以下代碼

if (m/foo/ || m/bar/) {
    s//PQR/;
}

可以改寫為:

if (m/foo/ || m/bar/) {
    s/${^LAST_SUCCESSFUL_PATTERN}/PQR/;
}

並且它將執行完全相同的操作。

地區類別 LC_NAME 現在在參與的平台上受支援

對於具有 GNU 擴展 LC_NAME 類別的平台,您現在可以將其作為 POSIX 中的 "setlocale" 的類別參數 來設置和查詢其語言環境。

不兼容的更改

readline() 不再清除串流錯誤和 eof 標誌

readline(),也寫作 <>,在流上發生錯誤後將不再清除處理的錯誤和 eof 標誌。

現在幾乎所有情況下都不再執行此清除,因此錯誤和 eof 標誌現在正確地反映了 readline() 後流的狀態。

由於錯誤標誌不再被清除,因此在流上調用 close() 可能會失敗,並且如果未顯式關閉流,則隱式關閉流可能會產生警告。

這導致了下游 CPAN 模塊中的兩種主要問題,這些問題也可能發生在您的代碼中

唯一一個在錯誤時持續清除錯誤和 eof 標誌的情況是在 miniperl 中的 glob() 讀取子處理程序時。這使其能夠在 close() 時正確報告子處理程序的錯誤。這在正常 perl 開發期間不太可能成為問題。

[GH #20060]

INIT 區塊在 BEGIN 中的 exit() 後不再運行

BEGIN 中執行 exit()INIT 區塊將不再運行。這意味著 -v 選項和 -c 選項的組合不再執行編譯檢查,同時顯示 perl 版本。在 BEGIN 區塊內部打印版本信息後,-v 選項執行 exit(0),而 -c 檢查是使用 INIT 鉤子實現的,導致 -v 選項優先。

[GH #1537] [GH #20181]

語法錯誤不再產生「幻影錯誤消息」

通常,即使在遇到編譯錯誤後,perl 也會繼續解析源代碼。在許多情況下,這是有幫助的,例如對於拼寫錯誤的變量名,顯示盡可能多的錯誤示例是有幫助的。但是,在語法錯誤的情況下繼續進行通常會產生奇怪的錯誤消息,甚至可能在編譯過程中導致段錯誤。在此版本中,編譯器將在遇到第一個語法錯誤時停止。這意味著任何期望看到我們以前產生的特定錯誤消息的代碼將會失敗。發出的錯誤將是以前產生的診斷之一,但在某些情況下,以前產生的某些消息將不再顯示。

詳情請參見 "現有診斷的更改"

utf8::upgrade()

從這個版本開始,如果輸入字符串是undef,它將保持undef。以前它會被改成一個已定義的、零長度的字符串。

"線程安全"語言環境的變更

Perl 5.28 在支持的系統上引入了"線程安全"語言環境,即現代 Windows 和支持 POSIX 2008 語言環境操作的系統。這些系統通過擁有每個線程的語言環境來實現這一點,同時繼續支持舊的全局語言環境操作,以供不使用新的每個線程語言環境所需步驟的代碼使用。

事實證明,一些 POSIX 2008 平台存在或曾經存在有缺陷的實現,這迫使 Perl 不使用它們。${^SAFE_LOCALES} 标量变量包含 0 或 1,以指示当前平台是否被 Perl 認為具有可用的線程安全實現。一些實現已經修復了,但 FreeBSD 和 Cygwin 最近被發現有足夠多的缺陷,以至於 Perl 不再在本版本中使用線程安全操作。因此,對於它們,${^SAFE_LOCALES} 現在為 0。可以通過在 Configure 選項中添加 -DNO_POSIX_2008_LOCALE 來配置舊版本的 Perl 避免這些有缺陷的實現。

在 v5.38 中修復了所有先前版本中導致語言環境不完全線程安全的錯誤。完成的第一個線程導致主線程(命名為thread0)恢復到啟動時生效的全局語言環境,丟棄線程的語言環境之前的設置。如果任何其他線程通過在 XS 代碼中調用 switch_to_global_locale() 切換到全局語言環境,那些線程將共享全局語言環境,並且thread0將不是線程安全的。

已棄用功能

使用'作為包名分隔符已棄用

在雙引號字符串中命名的變量中使用'作為包分隔符自 Perl 5.28 開始已發出警告。現在在字符串內插和非內插上下文中都已棄用,並將在 Perl 5.42 中刪除。

Switch 和智能匹配運算符

"switch" 功能和智能匹配運算符~~在 v5.10 中引入。它們的行為在 v5.10.1 中被顯著改變。當在 v5.18.0 中添加了 "experiment" 系統時,switch 和 smartmatch 被後續宣佈為實驗性的。多年來,有提案修復或補充這些功能。

在 v5.38.0 中,我們宣告該實驗失敗。一些未來的系統可能會取代 smartmatch 的概念位置,但目前尚未設計或建立。

這些功能將在 v5.42.0 中從 perl 中完全移除。

性能增強

模組與Pragmata

更新的模組與Pragmata

文件說明

新文件說明

perlclass

描述了新的class功能。

perlclassguts

描述了新 class 功能的內部。

現有文件的更改

我們試圖更新文件,以反映本文列出的更改。如果您發現我們遺漏了任何更改,請在 https://github.com/Perl/perl5/issues 開啟一個問題。

此外,已進行了以下選擇性更改

perlapi

perldeprecation

perlintern

perlexperiment

perlfunc

perlhacktips

perlop

perlvar

Diagnostics

對於診斷輸出,包括警告和致命錯誤消息進行了以下添加或更改。有關完整的診斷消息列表,請參見 perldiag

New Diagnostics

New Errors

新警告

現有診斷的更改

配置和編譯

測試

測試已新增和修改,以反映此版本中的其他新增和更改。此外,還進行了這些重大更改

平台支援

已停用的平台

Ultrix

已移除 DEC Ultrix 的支援程式碼。Ultrix 是數個 Digital Equipment Corporation 機器的原生類 Unix 作業系統。其最後版本發行於 1995 年。

特定平台注意事項

DragonflyBSD

跳過測試以解決 setproctitle() 中的明顯錯誤。[GH #19894]

FreeBSD

FreeBSD 不再使用線程安全的區域設置操作,以避免 FreeBSD 中的錯誤

uname -p 取代 archname 的第一部分。[GH #19791]

Solaris

避免 NetBSD/Solaris 中 regexec.c 和 regcomp.c 的一些編譯器和編譯問題。

Synology

為 DSM 7 更新 Synology 自述文件。

Windows

從 vmem.h 修正 gcc-12 所需的 win32 記憶體對齊。

如果在 Win32 上將 utimes() 失敗地轉換提供的 time_tFILETIME,則會將消息打印到 stderr。[GH #19668]

在某些情況下,由 stat()lstat() 返回的時間戳未考慮夏令時。[GH #20018] [GH #20061]

stat() 現在在 AF_UNIX 套接字文件上運作。[GH #20204]

readlink() 現在返回符號鏈接重解析點的 PrintName,而不是 SubstituteName,這應該使其更符合創建鏈接的名稱。[GH #20271]

在 Windows 上,lstat() 現在將連結目標的長度作為文件大小返回,就像在 POSIX 系統上一樣。[GH #20476]

在 Windows 上,symlink() 現在將目標中的任何 / 替換為 \,因為 Windows 不識別符號鏈接中的 /。 readlink() 不進行相反的轉換。[GH #20506]

當目標是絕對路徑到目錄時,symlink() 會錯誤地建立為檔案符號連結。 [GH #20533]

POSIX::dup2 現在不再建立壞掉的套接字。 [GH #20920]

關閉忙碌的管道可能導致 Perl 掛起。 [GH #19963]

內部變更

選定的錯誤修復

致謝

Perl 5.38.0代表自Perl 5.36.0以來大約12個月的開發,包含了來自100位作者的大約290,000行變更,涵蓋了大約1,500個文件。

在排除自動生成的文件、文檔和發行工具後,大約有190,000行的變更涉及到970個 .pm、.t、.c 和 .h 文件。

由於一個充滿活力的使用者和開發者社區,Perl在其第四個十年繼續蓬勃發展。以下這些人被認為對成為Perl 5.38.0的改進作出了貢獻。

Alex、Alexander Nikolov、Alex Davies、Andreas König、Andrew Fresh、Andrew Ruthven、Andy Lester、Aristotle Pagaltzis、Arne Johannessen、A. Sinan Unur、Bartosz Jarzyna、Bart Van Assche、Benjamin Smith、Bram、Branislav Zahradník、Brian Greenfield、Bruce Gray、Chad Granum、Chris 'BinGOs' Williams、chromatic、Clemens Wasser、Craig A. Berry、Dagfinn Ilmari Mannsåker、Dan Book、danielnachun、Dan Jacobson、Dan Kogai、David Cantrell、David Golden、David Mitchell、E. Choroba、Ed J、Ed Sabol、Elvin Aslanov、Eric Herman、Felipe Gasper、Ferenc Erki、Firas Khalil Khana、Florian Weimer、Graham Knop、Håkon Hægland、Harald Jörg、H.Merijn Brand、Hugo van der Sanden、James E Keenan、James Raspass、jkahrman、Joe McMahon、Johan Vromans、Jonathan Stowe、Jon Gentle、Karen Etheridge、Karl Williamson、Kenichi Ishigaki、Kenneth Ölwing、Kurt Fitzner、Leon Timmermans、Li Linjie、Loren Merritt、Lukas Mai、Marcel Telka、Mark Jason Dominus、Mark Shelor、Matthew Horsfall、Matthew O. Persico、Mattia Barbon、Max Maischein、Mohammad S Anwar、Nathan Mills、Neil Bowers、Nicholas Clark、Nicolas Mendoza、Nicolas R、Paul Evans、Paul Marquess、Peter John Acklam、Peter Levine、Philippe Bruhat (BooK)、Reini Urban、Renee Baecker、Ricardo Signes、Richard Leach、Russ Allbery、Scott Baker、Sevan Janiyan、Sidney Markowitz、Sisyphus、Steve Hay、TAKAI Kousuke、Todd Rinaldo、Tomasz Konojacki、Tom Stellard、Tony Cook、Tsuyoshi Watanabe、Unicode Consortium、vsfos、Yves Orton、Zakariyya Mughal、Zefram、小鸡。

上面的列表幾乎肯定是不完整的,因為它是從版本控制歷史自動生成的。特別是,它不包括向Perl錯誤跟踪器報告問題的(非常感激)貢獻者的名字。

在這個版本中包含的許多變更源於Perl核心中包含的CPAN模塊。我們感謝整個CPAN社區幫助Perl蓬勃發展。

有關Perl所有歷史貢獻者的更完整列表,請參見Perl源代碼分發中的AUTHORS文件。

報告錯誤

如果您發現了您認為是一個bug,您可以查看Perl bug數據庫,網址為https://github.com/Perl/perl5/issues。您也可以在Perl官方網站http://www.perl.org/上找到相關信息。

如果您認為您發現了一個未報告的bug,請在https://github.com/Perl/perl5/issues上開啟一個問題。請確保將您的bug縮減為一個足夠小的測試案例。

如果您要報告的bug具有安全影響,使其無法發送到公共問題跟踪器,那麼請參見perlsec中的“安全漏洞聯繫信息”以獲取詳細信息。

感謝

如果您希望感謝 Perl 5 Porters 在 Perl 5 中所做的工作,您可以運行 perlthanks 程式

perlthanks

這將向 Perl 5 Porters 列表發送一封電子郵件,表達您的感謝之意。

另請參閱

關於如何查看變更的詳細信息,請參閱 Changes 文件。

有關如何構建 Perl 的信息,請參閱 INSTALL 文件。

有關一般信息,請參閱 README 文件。

版權信息,請參閱 ArtisticCopying 文件。