autobox - 使 Perl 5 程式耳目一新
作者:gugod 發佈於: ,更新於: #perl在一些近代所發明的輕量語言裡,有這種語法:
# 2
["Hello", "World"].length
# "Hello World"
["Hello", "World"].join(" ")
["Hello", "World"]
表示一個陣列,而 .length
則是取前述陣列的屬性。 甚至也可以直接對此陣列調用陣列的方法 .join(" ")
。
這種可以將程式中原生資料型別 (primitive data type) 直接當成是物件來使用 的概念,稱為 autoboxing。在 Ruby 與 Javascript 的程式語言中,已經很簡明地直接成為其設計的一部份了。
在 Perl 5 中,則可以使用 autobox.pm 模組來輕易完成。
use autobox::Core;
"Hello World"->say;
當然不只是字面值可以做為物件來用,一般的純量變數也行:
use autobox::Core;
my $word = "Hello World";
$word->say();
光是這樣也許看不出倒底好在哪裡,畢竟只是把句子倒過來寫而已 (原本寫 say "Hello world",後來寫成 "Hello world"->say()),寫長一點的效果就明顯許多:
use autobox::Core;
my $word = "hello world";
$word->split(" ") # ("hello", "world")
->map(sub { ucfirst }) # ("Hello", "World")
->join(" ") # "Hello World"
->say; # say it!
這種主詞在前,後綴許多動詞的寫法,讀起來比以下一般用 Perl 5 會採用的寫法好讀一些:
say
join " ", # "Hello World"
map { ucfirst } # ("Hello", "World")
split(" ", $word); # ("hello", "world")
主要的原因在於閱讀的次序,前段程式碼要依照以下的順序讀:
say # 4
join " ", # 3
map { ucfirst } # 2
split(" ", $word); # 1
而改用後綴的寫法,閱讀順序如下:
$word->split(" ") # 1
->map(sub { ucfirst }) # 2
->join(" ") # 3
->say; # 4
可讀性顯然大幅提升。
想要立刻開始使用的讀者,請安裝 CPAN 上的 autobox::Core,與 autobox 雖分屬兩不同的散佈檔中, 但 autobox::Core 替原生資料型別提供的方法更加的完善、好用。autobox 提 供了基本能力,而 autobox::Core 則使其更加的實用。程式碼中只要 use autobox::Core 即可。
註一:
或許有人會認為我用了 map 所以才使得程式碼要倒過來讀,但不用 map 的寫法如下:
my @tmp = split(" ", $word); # 1, @tmp ==> ("hello", "world")
for(@tmp) { $_ = ucfirst } # 2, @tmp ==> ("Hello", "World")
$word = join(" ", @tmp); # 3, $word ==> "Hello World"
say $word; # 4
順序是好的,但卻需要另一個變數來暫存結果,使得這四列程式碼中,$word
與 @tmp
這兩個變數都使用了好幾次。這反而使其成為了最難閱讀的寫法之一。
註二:
這篇文章舉的例子完全是為了說明而造出來的,如果真的只是要把 "hello world" 轉寫成字母首字大寫,最快的方式是:
$word =~ tr/hw/HW/;
但這種解法也只僅對此特例最快而已 :)