替升級至 Perl 7 做準備

發佈於:

目前為止關於 Perl 7 的討論中,有不少篇幅是著墨於要如何幫助使用者們盡量容易地將現有的程式碼從 Perl 5 轉移到 Perl 7 去。目前已 Perl 7 裡,已知與 Perl 5 不相容的部份,只有嚴格模式 (use strict; use warnings;) 之使用。也就是說如果有某段程式碼仍需要將嚴格模式關掉才能正確無蟲地執行,那在 Perl 7 執行環境裡,就會壞掉,不改寫不行。

就我個人有限的經驗來看,無論是在 CPAN 上或是公司內私有的專案中,沒採用嚴格模式的程式碼已經很少了, 打 use strict; use warnings; 兩行程式碼已經差不多變成大家的肌肉記憶了。再說,只要使用 Moose 等物件系統,就會自動引入嚴格模式。除非真的有從哪裡找到二十年以上沒改版的程式,才有可能沒有 use strict 吧。

真的找到這種程式要來重構的話,要不就是非常難(太怪了沒人看得懂),要不就是非常簡單(變數宣告補一補就完工)。

那麼... 先假設這種程式在專案內不存在吧,如果要讓公司專案漸漸地移動到Perl 7 新語法的話,有甚麼好方法?

不過「Perl 7 新語法」,其實是個不太正確的說法。Perl 7 其實沒有提供新語法,但有提供新的語意。在 Perl 7 語言裡,就算沒寫 use strict; use warnings;,其嚴格模式的效果也依然存在。也就是說,如果目前專案中所有的檔案都帶有這兩列,那麼所謂的「使用新語法」,其實就是把那兩列統統移除掉。

但如果真的只是把 use strict; use warnings; 全部移除,專案的程式碼在Perl 5 中也依然能執行,但就變成在不是嚴格模式底下執行,說不定還會有一些怪怪的行為跑出來。

所以在目前,所謂「替升級做準備」,其實指的是找出一個可以不必寫use strict; use warnings;,也能啟用嚴格模式的手段。

基本上這很像是 common::senseModern::Perl 這類 CPAN 模組所提供的功能。當然,把程式碼中 use strict; use warnings 全換成use common::sense;use Modern::Perl; 說不定也是不錯的選擇。

但如果本來沒有使用這兩者,就變成要多加入新的相依模組。如果有「只要把那兩列程式碼刪掉」的解法的話算是最理想的吧。

我個人認為這解法依專案慣例而定。似乎不少專案都會有個最基層的模組是被很多其他模組所使用的。或許可以由此切入。

比方說,這裡有個 "Shop" 專案,底下有這些模組:

Shop.pm
Shop/Config.pm
Shop/Counter.pm
Shop/Member.pm
Shop/Product.pm
Shop/Card.pm

同時最上層的 Shop.pm 是被其他所有的模組使用。也就是說其他所有模組中,都有:

use Shop;

這一列程式碼。

如果是這樣的話,若我們將 Shop::import 函式定義為:

# Shop.pm
package Shop;
use strict;
use warnings;
sub import {
    strict->import;
    warnings->import;
}

其實就可以讓 use Shop; 一列同時也提供嚴格模式的效果。修改其他 .pm 時,只需要把use strict; use warnings 移除了就好,不必加上其他程式碼。

在多數 .pm 檔都已經包含 use Shop; 的這個大前提之下,這種做法應該是最省工的,比起改用 Moosecommon::sense 省事一些。如果日後需要引入其他新的語法機能,也可在此 import 之中添加。

如果專案中可能有很多個基層模組,逐一比較辦理亦可。

而等到專案本身以 perl7 執行之時,這 Shop::import 便可移除了。

我自己覺得這算是個比較省事的改法,但這方法或許有點爭議也說不定,又或許有更加省事的改法呢。