也許有許多人不理解 Perl 裡面為何有各種不是用英文字母名命的變數。原因之一是,其中一些是從 bash, csh, awk, sed 等各種其他腳本語言 (script language) 借來的。另有一些則是 Perl 自行發展的。

其中最常用的一個變數是 $_

在 Perl 語言的規範裡面,$_ 是非常多內建函式的預設參數。而因為這種特性使得程式語言讀起來相當簡潔,因此也有一些 CPAN 模組中所提供的函式也跟進這種做法:讓呼叫時如果沒有傳任何參數,那麼就假設使用 $_ 的值當作參數。

不過也因為這個變數是全域變數,雖然方便,過度使用的話其實會造成許多問題。因此慣例上來說,並不是永遠鼓勵使用。

關於 $_,我最愛的一種片語像是這樣:

say for @array;

for 迴圈 (或者 foreach) 的迭代變數,不指定的話,就是使用 $_,而 say (或者 print) 的預設參數,同時也是 $_

Perl6,以及 Perl5.10 語法中的 given-when 結構也會把被拿來測試的值裝進 $_ 中:

given ($foo) {
    when (1)          { say "\$foo == 1" }
    when ($_ > 100)   { say "\$foo > 100" }
}

我也非常喜歡這個特性。使得我常常在做的一件事更加明確了:

if ($_ = do_something() {
    if ($_ > 100) { ... }
    else { ... }
}

可以直接改成:

given( do_something() ) {
    when( $_ > 100 ) { ... }
    default { ... }
}

甚至讀起來都比較順口一些。

此外,我愛用的 zsh 也有直接使用 $_ 變數,可以如下進行指令:

# mv old-wrong-filename new-correct-filename
# chmod +x $_
# git add $_

這三個指令與以下指令相同:

# mv old-wrong-filename new-correct-filename
# chmod +x  new-correct-filename
# git add  new-correct-filename

基本上 $_ 只是前一個指令的最後一個參數而已。因此每做一個指令可能就會變,但只要掌握住這點,就可以更快的下達正確的指令。

附帶一提,在讀程式時,不防把 $_ 讀成「那個」,不要讀成「錢號底線」。會讓程式瞬間好懂一百倍。這點在 Perl 跟 zsh 都通用。