rubyでどっちのメソッドが人気か調べてみた

## 概要

さて、rubyのマニュアルを読んでいると同じ挙動だけど名前の違うメソッドがたくさん存在します。

代表としては`map`に対する`collect`、`inject`に対する`reduce`などでしょうが、このあたりはRubyの元にしたCommon LispとSmalltalkに存在するメソッドの両方の名前を採用したという歴史的経緯から、今の様な状態になっています。
どちらを使うのかは宗教論争と言われていて、どちらも使った人を自分も見たことはあります。
ただ、どっちを使った方が良いのか、そろそろ決着を見てもいいと感じたので、実際にはどちらのメソッドが人気なのか調べて見ました。

ちなみに、今回の調査対象は以下の様な基準で選びました。

1. [bestgems.org](http://bestgems.org/)でランキングされている人気のgemで、ダウンロード数Top 500のコードをサンプルにする
2. 各々のgemの中の`lib`ディレクトリ以下を調査の対象とした。つまりはテストのコードは集計から排除した
3. 動的な言語なのでどのクラスに属しているかの推論は諦めて、あくまでメソッド名の集計結果とした。

Webプログラミングのためのものが多いとは言え様々なツールが入り乱れているrubygemsのコードを集めれば、熟達したRubyistのコードでしょうし、自分なりには妥当な基準だと考えています。

集計のためのコードは[github](https://github.com/baban/ruby_mehod_statistic)上に、公開しておきます。
幾つか構文解析に失敗したファイルなども出ますが、統計的に無視して良い程度だと思われます。

## 結果
さて、では結果を順番に見ていきましょう。

まずは一番よく目にして気になっているであろうEnumerableモジュールの中のメソッドです。

| Slalltalk由来 | 使用回数 | Common Lisp由来 |　使用回数 | | |
|:---:|:---:|:---:|:---:|:---:|:---:|
| collect | 870 | map | 6843 | |
| inject | 982 | reduce | 222 | |
| keep_if | 10 | select! | 20 | select + select! 合計 | 1629 |
| delete_if | 299 | reject! | 193 | reject + reject! 合計 | 893 |

結果としては、それぞれ傾向はあれど、どちらのメソッドも使われている状態でした。
由来とした言語には関係が見えませんね。

意外だったのは`delete_if`メソッドの方が`reduce!`メソッドより多かった事ですね。
`delete_if`は、実は「!」が付いていないのに破壊的メソッドという初心者が陥りがちなバグを生成する、落とし穴を持っているメソッドなので、好んで使う人がいたことに驚きですし、視覚的に分かりやすく、綴りも短い`reject!`メソッドよりも多いのがなお驚きです。
ただ、「!」の無い`reject`メソッドが671回使われているので、これを足し合わせると`reject`と`reject!`合わせて、893回使われています。
中の実例を見ていませんが、そもそも`reject`を使って破壊的なメソッドとして扱わない方向に書き改めているのかもしれませんね。
`select!`メソッドこそ仕様回数20回ですが、`select`メソッドは1609回と圧倒しているのもその証左でしょう。

やっぱり基本的には短くて分かりやすい名前を選んでいるという傾向に見えますが
それ以上の理由は見えない感じですね。

`inject`と`reduce`に関しては、`inject`の方がよく使われていますが、これに関しては書籍では`inject`を使う例が多いのが理由と推測できますね。

それでは、その他のメソッドに関して順番に見ていきましょう。
メソッド名に関しては短い名前の方を先に掲載して、長い名前の方を続いて並べました。
仕様回数の多いメソッドから順番に掲載していっています。

| 順位| 短い名前のメソッド | 使用回数 |  長い名前のメソッド |　使用回数 |
|:---:|:---:|:---:|:---:|:---:|
| 1 | each | 11728 | each_pair | 378 |
| 2 | is_a? | 7404 | kind_of? | 919 | 
| 2 | size | 4055 | length | 2799 |
| 4 | send | 3183 | \_\_send\_\_ | 440 |
| 5 | marge! | 2727 | update | 506 |
| 6 | dup | 2471 | clone | 369 |
| 7 | path | 1926 | filename | 228 |
| 8 | key? | 1723 | has_key? | 1173 |
| 9 | select | 1609 | find_all | 172 |
| 10 | pos | 1334 | tell | 13 |
| 11 | fail | 932 | raise | 14119 |
| 12 | class_eval | 703 | module_eval | 469 |
| 13 | pwd | 220 | getwd | 10 |
| 14 | next | 215 | succ | 21 |
| 15 | abs | 192 | magnitude | 1 |
| 16 | flat_map | 191 | collect_concat | 0 |
| 17 | to_enum | 160 | enum_for | 86 |
| 18 | local | 92 | mktime | 1 |
| 19 | tty? | 74 | isatty | 2 | 
| 20 | class_exec | 26 | module_exec | 10 |
| 21 | rmdir | 15 | unlink | 136 |
| 22 | conj | 6 | conjugate | 0 |
| 23 | imag | 5 | imaginary | 0 |
| 24 | gm | 4 | utc | 279 |
| 25 | eof | 3 | eof? | 128 |
| 26 | value? | 8 | has_value? | 5 |
| 27 | iterator? | 0 | block_given? | 1505 |

先ほども言いましたが、一般的な傾向としては、**短い名前のメソッドの方がよく使われているし、使用頻度の高いメソッドほどその傾向がある**という感じでしょうか、ただ例外も多いです。

例えば`raise`と`fail`、`iterator?`と`block_given?`は圧倒的な差で綴りの長い方が使われています。
`iterator?`はそもそも公式ドキュメントで使用が推奨されていないという理由がありますし、`raise`は[公式ドキュメントでそちらを紹介している](https://docs.ruby-lang.org/ja/2.4.0/doc/spec=2fcontrol.html#raise)のでこれも分かります。
また、`File#eof`と`File#eof?`に関しては、ファイルの終端に達しているかどうかを調べるメソッドですが、値がBooleanを返すため末尾に?の付く`File#eof?`が圧倒的に好まれています。
ハッシュに指定したキーが存在しているかを調べる`Hash#key?`と`Hash#has_key?`は、それぞれ1723回と1173回と、名前の長さの違いの割に２倍以下の使用回数の差に収まっています。
これだけの綴りの長さの差があってもやはり、`key?`だけでは「持っている」いうニュアンスが抜けてしまうのが気になるのでしょうね。
`Module#class_eval`と`Module#module_eval`も1文字程度の文字の違いを気にするよりは、使われる文脈がclassとmoduleどちらの内側で使われているかで使い分ける方が良いという風に考えられているのでしょう。
使用回数に大した差が見られません。

上記の様に、名前の短いことは好まれる理由の一つですが、論理と名前の整合性で違和感が表に出るものは、名前の長さよりもそちらが優先される。
また、Rubyの公式ドキュメントのサンプルコードでどちらが使われているかは大きな判断材料になっている状態で、全体像は若干複雑な様子です。

## 結論

さて、Rubyで人気のメソッドを参考に比較を行って見ましたが、個人的な結論としては調べて見た感じとして、**使用回数に５倍以上の開きがあるものに関しては、勝負は決した**として人気のある方にみんなもう寄せてしまっていいのではないかな、という印象を受けました。
あくまで私感ですが。

今回、調べて見て他にも面白い事が見つかっていますが、まぁそれに関しては別の記事で扱うのが良いでしょう。
何かしら参考にしていただけたなら幸いです。