はてなインターンと初めてのPerl

というわけで、現在はてなサマーインターンに参加中です。
インターン期間も半分が過ぎ、いよいよ佳境に入っていくわけでありますが、このエントリで話したいことは、Perlについて。
ご存知のようにはてなではPerlを使ってサービスが実装されていますが、私はこのインターンが決まるまでまったくPerlを触ったことがなく、たまに見かけるPerlのコードを見かけては、$@%など記号が多くてよくわからない言語だと思っていました。一方で、Plaggerなどが代表的なCPANモジュールという他の言語にはない魅力があったので兼ねてから勉強したかった言語でもあります。
んで、インターンが始まってから2週間、毎日というわけではありませんが、Perlに触れてきて、それなりに自分で書きたいものが表現できるようになってきたので、今現在のPerlへの感想について。

前提

私の母国語はJavaで経験は大体3年ぐらい。
作ったものはWeb関連のものが多い。
PHPPythonJavascriptも必要に応じて少々。

リャマ本とアルパカ本を読んだ

インターンに参加が決まったのが7月の22日で、そこでPerlの基礎的なことは勉強してくるようにとのことでしたので、このあたりを参考にして、あわててAmazonで本を買いました。
初めてのPerl』と『続・初めてのPerl』はインターンが始まるまでに読んでおきたかったのですが、ちょうど「こうなる。」のリリースと期間が重なっていたので、サービスの不具合修正やアップデートと平行しまい、『初めてのPerl』は読めたのですが、続のほうはリファレンスの話までしか読めませんでした。
個人的に面白かったのは、elsifというつづりについての注釈です。

実際、彼は「別の綴りとしてelseifも使えるようにすべきだ」という提案には、反対しています。「もしeをもう一個持つ綴りを使いたければ、それは簡単なことだよ。ステップ1---自分で言語を作る。ステップ2---それをみんなに使ってもらう。」とLarryは言っています。

http://www.amazon.co.jp/%E7%B6%9A%E3%83%BB%E5%88%9D%E3%82%81%E3%81%A6%E3%81%AEPerl-%E6%94%B9%E8%A8%82%E7%89%88-Randal-L-Schwartz/dp/4873113059


はてなインターンで必要なPerlの知識ですが、他の言語である程度プログラムを書いている人なら、練習問題をやることを含めてこの2冊を読んでいれば、なんとかついていくことができると思います。逆に、他の言語をいくつかやっている人のほうが、カリキュラム的には楽しいかも。
とはいえ、実践的なコードを書かなければコーディングは上達しませんので、この辺りは実際にカリキュラムの中で毎日書くことで現在も勉強させていただいています。


Perlに触れての感想

Perlの変数は大きく分けて3種類で、スカラ・配列・ハッシュで、それぞれ変数名の前に$・@・%を付けます。覚えることが少し多いと感じることもありましたが、順番に書けることが増えていくので、それほど苦痛ではありませんでした。
『初めてのPerl』ではファイル操作についてかなり多く話を割り振っているので、純粋にWebアプリを作りたい人だとこの辺は退屈に思うかもしれません。
ただ、実際にサービスを運営していると定期的に実行するファイルの文字列操作スクリプトが必要になってくることは結構あります。その辺はEclipseを使って書くJavaだとあまりお気軽に書けないところでもあるので、個人的には言語としてファイル操作に特化した記法や性質を持っているところが面白く、また便利に感じられました。
はてな社内ではオブジェクト指向が推奨されているので、Javaで慣れ親しんでいるクラス設計自体はそれほど難しくなかったのですが、実際に開発する際のディレクトリ構成やサブルーチンへのメソッドの渡し方などは慣れるまで結構かかりました。


リファレンスの重要性の把握

リファレンスの使い方がなんとなくわかってきたのは、はてな社内製のMoCoというO/RマッパーやRidgeというWebフレームワークを触り始めて。
サブルーチンに値を渡すときに、他の言語と同じ感覚でやっていてハマることが何度かありました。Perlだと引数は配列として渡されるので、配列やハッシュをうまく渡すにはリファレンスを活用する必要があります。フレームワークのサブルーチンへの値の渡し方を見て、「なるほど、Perlではこういう風にリファレンスを使って渡すのか!」と合点がいきました。
OOでのデリファレンスの仕方に慣れてきたのもこの辺りです。
優れたインターフェース設計を見ることで、Perlっぽいサブルーチンがかけるようになってきました。


Perlの気に入ったところ

ハッシュ周りの処理記法と正規表現が良いです。
RubyなりPythonなりPHPなりを触ったときにも思ったのですが、ハッシュ(連想配列)が手軽に使えるので、引数に使ったりクラスの代わりに使ったりといろいろ汎用性があります。JavaだとHashMapというクラスにしてしまったので、汎用性が上がった分、上記のスクリプト言語のようにお手軽に使うのは難しくなってしまっています。
あとやはり正規表現が強力なところはよいですね。


Perlのイケてないと思ったところ、違和感を覚えたところ

まず気になったのが、use strictやuse warningsやmyについて。これらは必ず書くことが推奨されるので、慣れれば気にならなくなるのですが、デフォルトで有効にしていればよいのに、と知ったときに思いました。この辺は古いバージョンとの互換性を保つためでもあるのだろうし、Perl自体の言語思想も何かあるのでしょうかね。
もう一つは、サブルーチンでの引数の受け取り方。

sub hoge {
    my($self, @arg) = @_;
    ......
}

のようにPerlでは書くのですが、最初は使いにくく感じました。慣れてくると柔軟に引数を受け取ることができることもわかってきたので、必ずしもいけてないとはいえないですけどね。
あと、forやifが後置できることや、mapなどの順序のあたり。

# @listの中身をprintする
print $_ foreach @list;

# シュワルツ変換(比較的重い処理を前処理してからソートを実行する)
# 一番下のmapから実行される
@sorted = map{$_->[0] }
    sort{$a->[1] cmp $b->[1]}
    map{ [ $_, hoge $_ ] } @data;

基本的に上から下へ左から右へという実行順序に慣れていると、少し戸惑います。一行でかけるので書くほうとしては書きやすいし、知っていれば間違うこともないのですが、場所によってはコーディング規約で禁止してるところもありそう。


はてなPerlを学んだことのメリット

最初の一週間ははてな内でしかPerlerに触れていなかったので、Perlerの人は皆今風な書き方をしているような錯覚をしていたのですが、8月10日に行われたkansai.pmでの「続・脱KENT様方式」*1のプレゼンを聞いてハッとしました。当然のことですが、Perlを書く人にもピンからキリまでいて、一つのplファイルにべた書きでサブルーチンの一つもなくてグローバル変数使いまくりな人もいるわけです。
自分自身も独学でPerlをやっていたとしたら次に読んだのは適当なCGIの本だったかもしれないですし、そこで今風なPerlの書き方が学べたかどうかはあやしいです。
そういった意味で、はてなの中のプログラマの方に指導をしてもらって、実際に模範回答のコードも読む機会が得られるということが、Perlを学習効率の高速化の起爆剤となっているのだと思います。テストについても言及されていて、プログラムを書く上で本質的に重要なところがうまくピックアップされています。
あと、大規模データを扱うプログラムをPerlで書いたりしたのも、Perlでメモリを意識するきっかけになってかなり勉強になりました。Perlだと普通にクラスを使って書くとメモリを食いまくるので、必要なところだけをクラス化して、大量のデータはハッシュや配列などをプリミティブなまま持っておくのがよいようです。


終わりに

現在の環境では後々の運営を考えると、Perlで書いたコードを本番で運用するということはないのですが、今後は最初のプロトタイプを作るうえではPerlで書くのが良いかなと思っています。
Perlで書くことに慣れてきて、言語自体が好きになってきたこともありますが、やはりCPANモジュールの豊富さが一番の要因です。煩わしい部分をライブラリでラッピングして、やりたいことに集中できると生産性も上がりますし、ソースコード自体を参照できるということも大きな利点です。
そういった意味で、次に学ぶことはCPANの有効利用方法ではないかと思っています。

*1:まだ資料は公開されていないようなので、http://www.azurestone.org/text/contents/#STDA20080810前回のものはhttp://d.hatena.ne.jp/azurestone/20080602/1212343947です。