自明なコード

青木峰郎さんの「正しいRubyコードの書き方講座」の本を、いまさらのように買って読んでいる。勉強になるのだけど、以下に引用した添削のbefore / afterにびっくりした。

Wikiの*を個数に応じてh1、h2などのタグに開くコードだけど、最終的に4行にしてしまっている。なるほど、短いし、*をリテラルじゃなくて個数で汎用的に扱うなど美しいのかもしれないけど、ソースコードが他者とのコミュニケーションのためのものだとすると、ぼくには改悪にしか思えない。だって、

   h_regexs = {
     '*'    => 'h' + @h_start_level.to_s,
     '**'   => 'h' + (@h_start_level + 1).to_s,
     '***'  => 'h' + (@h_start_level + 2).to_s,
     '****' => 'h' + (@h_start_level + 3).to_s,
   }

のほうが、

   level = @h_start_level + (line.slice(/\A\*{1,4}/).length - 1)

よりも、なにがしたいか一目瞭然じゃん。エディタで開いて1秒で意図が分かる。これって自己満足じゃないのかしら? 馬鹿馬鹿しいぐらいストレートに書いたほうがいいってことないのかな。(line.slice(/\A\*{1,4}/).length - 1)を人間が脳で展開するコストってバカにならないと思うし、人によってはトリッキーにすら感じるレベルだと思った。*が100個並ぶ可能性があるなら、ロジックに落としたほうがいいのだろうけど、4個しかないんだし。

String#sliceって、例えば、"abc"[/b/]とか、"abc".slice(/[bc]/)みたいに使う、「きたなRuby、すごいぞRuby」とでも言うべきメソッドだと思うんだけど、そういうRubyらしさをどこまでも追求することが良いことなんだろうかというのは議論の余地ががありそうな。

……と書いてきて、青木さんの本を読み進めたら、いきなりぼくの感想に対する反論があった。セミナー会場で、「元のコードのほうが自明でいいのでは?」という質問があったそうだ。やっぱり。

で、青木さんのロジックは「より多くの人が知っているメソッドだけを使ったほうがいい」のには賛成するけれども、String#sliceなんてどんだけ古くて超基本のメソッドだと思ってるんだ? 使おうぜ、というものだ。これはおかしい。人間に理解しやすくするのが目的だと言いながら、String#sliceが(多くの)人間に理解しやすいかどうかの議論を主観ですっ飛ばしている。誰もがコアクラスのメソッドぐらい熟読しておくべきという理想論はあるとしても、だって、現実そうじゃないんじゃないのという認識があるとしたら、やっぱり使わないほうがいいメソッドがあり得るようにも思える。C++ハッカーの知人が、オレがテンプレート全開で書いたら、チームのほかのメンバーが分からなくなるから使わないんだと言ってたのは、そういうことだと思う。

PythonからRubyに来る人、PHPから来る人、いろんな層がいるわけで、Rubyを使う人達の習熟度を常に90%と想定するのってどうなの? ライブラリのコードなのか、アプリケーションのコードなのかでも議論が違ってきそう。

自然言語でも習熟度はさまざま。だから語彙が豊富な母語話者であっても、子どもや外国人に対しては語彙レベルを下げてしゃべるのはまったくふつうのこと。せっかく日本語にはズバリの語彙があるんだし、なんで使ったらダメなんだという議論は、コミュニケーションの目的を軽視してるように思える。

……、と書いてさらに半分ぐらい読み終わったところで、いや、やっぱりコアクラスのメソッドや正規表現のオプションとか、ちゃんと便利なものを全部分かって使いこなしたほうがいいんだろうなという風に思い始めている。正規表現のxオプションとかすげえな、なんで知らなかったんだろうと思う。たぶん読んだことはあっても「へぇ」という感じで流してたんだろう。

それにしても、他人のソースコードの添削っていうのは面白いな。「さすがにこれはないだろう……」というコードをザックザクと切り捨てていく様が痛快ですらある。大変勉強になる。実例を伴って、オブジェクト指向における設計について、考慮すべき基準や方針を列挙してくれているのも貴重かも。