privateって書きたくない

まず前提として

  • publicにするべきものはpublicにするべき(公開されたAPIであるもの)
  • privateにするべきものはprivateにするべき(公開すると都合が悪いもの)

である。ところが、残念なことにこの二つの間には、どちらとも言いがたいものがかなりの分量あったりする*1。それをどうするべきなのかというと、簡単に言うと(理論上)二つの戦略を考えることができて*2

  • 良くわからないやつは全部publicにする
  • 良くわからないやつは全部privateにする

それで、僕は前者を選択しがちであるという話。もちろんケースバイケースで、ライブラリを作ってるときはできるだけprivateにするし、例えばattr_accessorattr_readerだったら後者を選ぶし、まあ基準としては曖昧なんだけど。あるいはObjective Cだと、ヘッダファイルを書くのが面倒なのでPrivateにする(宣言しない)という現象が発生するし、NSMutableArrayNSArrayであればNSArrayを選ぶ。


https://github.com/soutaro/unification_assertion/blob/master/lib/unification_assertion.rb

例えば、上のプログラムで言うと、UnificationAssertion#substituteなんかが、僕の言うところの「どちらとも言いがたいもの」である。

これはUnificationAssertionモジュールの外からは呼ばれないメソッドなのでprivateでも良い(公開されたAPIとは言えない)。コメントも書いてないので、実装した人(1年前の僕)もpublicなAPIであるとは認識していないことが推測できる。一方で、この操作はこのプログラムにおいてかなり本質的な操作なので、「実装の詳細なので隠蔽しなくてはいけない」と言うほどの物でもない。その辺を考えた結果「privateにするべきものでもないのでpublicのままにしておこう」となった。

ちなみに、例えば代入に対応するクラスを定義せずにHashをそのまま使っていたりメタ変数のためにシンボルを流用しているように、かなりプログラム全体のサイズを小さくすることにも注目して実装している。この「1ファイルで完結するくらいの小さなプログラム」であるという事実も、privateとpublicのどっちの戦略を採用するかにかなり強く影響している。


アプリケーションを書いているときに、こういう些末なことに頭を使いたくないという感覚も大きい。Webアプリケーションを書いてるときに、上のsubstituteメソッドの可視性について考えることには時間は使いたくない。

こういう、publicなものを好む嗜好というのは、僕の場合にはかなり最近に後天的に獲得された物である。ソフトウェアのモジュールがどのような関係を持っているべきなのか、というのは実際にはけっこう考えるのが楽しいことなので、放っておくと時間を忘れて(しょうもないことを)考え続けてしまう。そういう状況は避けるべきなので、些末なこと、つまり超重要ではないことに悩み始めたら考えるのを止めて、ひとまず最小のタイプ数で制約を満たすものを選ぶような、そういう思考を行うように教育した。ような気がする。

*1:理論上はないというのは理解できるけど、どこまで行ってもどこかに分水嶺があって、さらにその上にかかるものがあってしまうことは、それほど特殊な状況ではないと思う。

*2:別にもっと考えても良いけど。