2013年5月16日
Perlの引数の渡し方の想像上の歴史
一般的な以下の様な渡し方について。
func($foo, $bar);
func({foo => $foo, bar => $bar});
func(foo => $foo, bar => $bar);
昔は1だったけど、2って書けるのも分かりやすくて良くね?ってなって、1でも2でも指定できるような書き方が出てくるようになった。
だんだんこの場合は1にすべき2にすべきっていう住み分けができてきて、両方の指定ができるみたいなのが減ってきた代わりに、じゃあ3の書き方で良くね?ってなってきた。今度は、2でも3でも指定できるみたいな書き方が出てくるようになった。
僕は最近は3決め打ちで良くね?って感じてきている。MouseとData::Validatorを便利に使わせてもらってるんで結果的には両方いける感じになっていることが多いけど。
値をhashに詰めるのとhashrefに詰めるのどっちが好きかって好みの問題もありそうではある。僕はタイプ数が減らせるし、なるべくhash使いたい派。逆に色々sigil使いたくないって人はなるべくhashrefに統一するのもひとつの手だとは思う。
2だと参照渡しになる分若干早くなるのかもしれないけど、逆に意図せず値が書き換わるリスクがある。事前に値をhashrefに詰めておいて、後でガバッとメソッドに渡すやり方をするとそういうバグが起きやくすくなる印象。
3だと順番も保持されるし同じキーを複数回指定するみたいなのもハンドリングしようと思えば可能なのも良い感じ。
1の使いどころも勿論あって、引数が1つか2つで明らかにそういう渡され方をするってのが客観的にも自明であれば使ってもいいと思う。その場合英語的に自然かどうかってのも大事な判断材料だと思っている。 $s->v($o, $c);
みたいな。
英語に自信がないのであれば(僕もない!)、引数が少なくても迷わず3の形の名前付き引数を採用するのが安全かなーと思います。
【追記】
fujiwaraさんの体感値だと、
func($foo, $bar)
-> func( foo => $foo, bar => $bar )
-> func({ foo => $foo, bar => $bar })
の順で見かけるようになったとのことです。確かに、perl4の時代はHashRefとかなかったので、Hash渡ししかできません。実際、歴史あるCGIモジュールはHash渡しになってます。
https://metacpan.org/module/CGI#SYNOPSIS
- Catalist, DBIC辺りから、HashRef渡しをよく見るようになった
- 最初はhash直で、その後hashref渡しが流行って でもぜんぶhashrefって微妙じゃね、ってなって揺り戻しが来てる感じかなあ
というお話で、そっちの方が正しい感じがします!