外国人が語る：英語でクラスやメソッド等の名付け方

アメリカ人です。 Hello 👋

# この記事の目的
多くの日本人は自分の英語力には自信がないではないでしょうか。残念ながら「英語がわからん」、「英語が全然できない」という声をしょっちゅう聞いています。でも、今まで英語ができて意味がちゃんと伝わる何人かの日本人に会ったがあります。完璧な英語ではないけど(外国人も英語でミスる時もある...)、がんばって話そうとするので充分仕事ができる人たち。そういうがんばる姿勢はオープンソースのプログラムや英語圏のプログラムに手を出すためには一番大事なことだと思います（外国人側もすごく助かります）。日本の文化では「私はできる！」と自慢することは少ない中、この記事を通して、流暢に話せなくても自分のプログラミングの命名の仕方にはちょっとだけでも自信を持たせたいなと思います。完璧じゃなくていいです。[Let's go!](https://www.youtube.com/watch?v=T383N0Qsk7g)

# 合わせて読んでいただきたい
1. <a href="https://qiita.com/hironori_narita/items/4b06db0953053d41c4a0">【日本人エンジニア必携】英語命名規則の決定版</a>
2. <a href="http://qiita.com/Ted-HM/items/7dde25dcffae4cdc7923" target="_blank">プログラミングでよく使う英単語のまとめ【随時更新】</a>
3. <a href="http://qiita.com/KeithYokoma/items/2193cf79ba76563e3db6" target="_blank">うまくメソッド名を付けるための参考情報</a>
4. <a href="http://qiita.com/koitaro/items/c3720d9c3ac1e7b0590f" target="_blank">クソコードにならない為に、これだけは守って欲しい７つのこと</a> <- （特に「コメントは綺麗に書こうとするな。思いを込めろ！！！」の部分）

# 概要
1. 英文らしい書き方
2. 極力、引数も含めて、クラス、メソッドや引数を１つの文章として扱うこと
3. 区切りをなくすこと
4. 変数などの長さ・省略する時の落とし穴
5. その他のオープンソースからの例

# 1. 英文らしい書き方
筆者は普通はRubyを書いていますが、RSpecがものすごく好きです。

```ruby:example_spec.rb
it { is_expected.to eq(10) }
```

実はRSpecで初めて見たのはdeprecatedになった「should」の方だったけど、これを見たら、「え！？これはアリなん？？普通の英語の文章を読んでるみたい！」と思って印象に残りました。でもよく考えてみれば、JavaからRubyの勉強を始めた時、またPythonの方を見た時にも、同じような印象が残りました。要するに、コードがただ単語の集まりになっているのではなく、文章を読んでいるみたいな感覚が印象に残りました。

実は、プログラミング言語やフレームワークがますますこう展開していくじゃないかと思います。つまり、将来のプログラミング言語はRSpecやshoulda_matchersみたいに、英語の文章を読むような形に、もっとそうなるのではないかと。こういう書き方を見ると、「ああ、これはいいな〜、読みやすい！」と思ってきます。

ということでポイントです
<strong>作りたい英文を考えた上で実装すること</strong>

キーワードは「文」です。単語だけで済むならそれももちろんいいのですが、文が作れそうなのであれば、文を作りましょうという考え方です。書きたいメソッドだけじゃなくて、クラスが何に対して何をするか、という全面的な考え方から始めて、自分の作りたい英文を書くこと。試しに何文かを書いてみてください。

# 2. 極力、引数も含めて、クラス、メソッドや引数を１つの文章として扱うこと
クラスは大体名詞になっていますよね。ゲームを作る時は`Player`とか、サービスを作る時は`User`とか。
オブジェクトはそもそも何らかのものなのでこれは分かりやすいと思います。

メソッドの命名でこけることが多いではないでしょうか。
簡単な例なんですが、次のプログラムを見てください。

```ruby:game.rb
TYPE = { heart: "♥", diamond: "♦", club: "♣︎", spade: "♠︎" }

class Deck
  attr_accessor :cards

  def initialize
    @cards = []
    TYPE.each do |key, value|
      1.upto(10) { |n| @cards.push({type: key, value: n}) }
    end
    @cards.shuffle!
  end
end

class Player
  def initialize(name)
    @name = name
  end

  # valueで整理する
  def order(deck)
    deck.cards.sort do |a, b|
      a[:value] <=> b[:value]
    end
  end
end

player1 = Player.new("p1")
deck = Deck.new
player1.order(deck)
#=> [{:type=>:club, :value=>1},
#=> {:type=>:heart, :value=>1},
#=> {:type=>:diamond, :value=>1},
#=> {:type=>:spade, :value=>1},
#=> {:type=>:heart, :value=>2},
#=> {:type=>:spade, :value=>2},
#=> ...
```

こんな書き方だと、

```ruby
player1.order(deck)
```

という書き方ができて、かなり読みやすい。

最近は次のような書き方を見て、少し気になりました。

```ruby
def order_deck(deck)
```

メソッド名を見るだけで分かるような名前なんですけど、メソッドは引数とペアになることが多いから、メソッド名と一緒に引数を合わせて文章を作ると結構簡潔に書けると思います。
RSpecやshoulda_matchersはこれを充分に実現しています。

ということで、またポイントです。
「<strong>主語 + 動詞 + 目的語</strong>」という書き方が読みやすい！
主語 = クラス
動詞 = メソッド
目的語 = 引数

しかし、「主語 + 動詞 + 目的語」と書かないとダメだというわけではありません。
「動詞 + 前置詞 + 名詞」とかいう場合もあります([railsからの例](https://github.com/rails/rails/blob/f481353150c100dbd944d5aa84f2480264cd723c/activemodel/lib/active_model/attribute.rb#L135))：

```ruby
def encode_with(coder)
```

あくまで、何が何に対して何をするかというのを明確にして、できるだけ文章を読んでいるみたいな形として書くことです。それをするための一つの手としては、引数をメソッド名から分離するのではなく、一つの文章(もしくは文章に近い形)にすることです。

筆者は最近こんなメソッドが書きたかったです。
`Player`は`score`があって、ゲームが進むと点数が入る、というロジックです。
英文を考えたら、「Add 1 to score」がパッと頭に浮かんできました。
でもそうすると次のようになってしまいます...

```ruby:player.rb
def add(num)to_score
  @score += num
end

player1 = Player.new("p1")
player1.add(1)to_score
```

構文エラーが生じてしまうのでこれはダメですね。
読みやすいからこんな書き方ができたらいいのにな〜と思いましたが、
改めて考えてみると、これは普通にこう書いていいですね

```ruby
# メソッドを書かなくてもいい
player1.score += num
```

この場合だと簡単に済みますが、他の例を見てみましょう。

[CanCanCan](https://github.com/CanCanCommunity/cancancan)というライブラリーはこういう書き方をしているのでおすすめです。
(下記は[ドキュメント](https://www.rubydoc.info/github/CanCanCommunity/cancancan/CanCan/Ability#can-instance_method)からです)

```ruby
ability = Ability.new(user)

# ここでは動詞のdestroyは引数に含まれていて、
# 第二の引数は目的語なのですが、考え方は一緒です。
ability.can? :destroy, @project

# さらに読みやすさをアップするために変数の名前を変えてみる
user_ability = Ability.new(user)
user_ability.can? :destroy, @project

# CanCanCanには存在していない書き方ですが、
# あえて別の書き方をしてみる。
user_ability.can_destroy?(@project)
```

前のゲームの例を振り返って他のメソッドをこう書けそう：

```ruby
player1.draw(card)
player1.send(message)
```

# 3. 区切りをなくすこと
Rubyではtrueかfalseを確認するためには、「?」のメソッドをよく使います。

```ruby
# 真偽を返す
def has_heart?
  @card_in_play[:type] == :heart # 出したカードをチェックします
end

if player1.has_heart?
  puts "You have a heart!"
end
```

Rubyでは`then`を使って文をつなぐことができますが、こう書くと、文章が二つになってしまい、区切り(「間」というべきか)が入ってしまいます：

```ruby
if player1.has_heart? then puts "You have a heart!" end
```

これを解決するためには次の書き方ができます。
```ruby
puts "You have a heart!" if player1.has_heart?
```

ただし、個人的に(気持ち的に？)`if`から始めたいからこう書きたいです：

```ruby:true_or_false.rb
# はてなを消してみました。
def has_heart
  @current_card[:type] == :heart
end

if player1.has_heart then puts "You have a heart!" end
```

こんな感じだと、`then`との関係においては違和感がなくなります。
「?」を使う書き方には慣れたのでもう違和感を感じませんが、これも変数やメソッドなどを名づける時に心がけるべきところの一つなのじゃないかなと思います。

<a href="http://qiita.com/KeithYokoma/items/2193cf79ba76563e3db6" target="_blank">うまくメソッド名を付けるための参考情報</a>の「真偽値を返すメソッド」のところはいいと思います。

また、[【日本人エンジニア必携】英語命名規則の決定版](https://qiita.com/hironori_narita/items/4b06db0953053d41c4a0#%E5%A4%89%E6%95%B0)の「変数」のところもいいと思います。

作りたい文章の中で余計な間が入っていると感じれば、メソッド名や、if文、while文などを考え直してスッと読めるように作り変えましょう。

# 4. 変数などの長さ・省略する時の落とし穴
これは英文と関係はないですが、たまに気になることなので何か書いておきたいと思いました。

「合わせて読んでいただきたい」で挙げた<a href="http://qiita.com/koitaro/items/c3720d9c3ac1e7b0590f" target="_blank">クソコードにならない為に、これだけは守って欲しい７つのこと</a>からです。こう書いてあります：

> 「なぜ？」と疑問を持たれるコメントを残すな!!

コードのメソッド名、変数名なども同じです。
最近は「Pelmanism」という言葉を人生で初めて見ました。英語は第一言語なのに、どういう意味か全く分かりませんでした。

その言葉を紹介した人の話を聞いたら、「Pelmanism」とは「神経衰弱」という意味らしいです。「神経衰弱」のことをずっと「Memory Game」という風に呼んできた私はびっくりして、なるほど、英語にしたい言葉を辞書で調べるとこうなる時があるんだと感じました(逆に言えば筆者も知らない日本語を調べるたびにこういうことが起こりそうなんだなと思いました...)

中学校で英語を教えていた時も同じような感じでした。
生徒が原稿を書く時に、何人かがまず日本語で書いてしまい、
Google翻訳を使って分からない単語や文法を書くことが多かったです。
そうすると、正しい英語が出てくる時もあれば、書きたい単語や文法はまだ
習っていないので全然違う英語か、難しすぎて自然じゃない英語が出てきます。
レッスン毎にちゃんと文章に成り立つための単語や文法を勉強しているから、
まずその単語や文法から始めて文章を作るのが一番ベストで確実です。
より複雑で詳細な文章を書きたい気持ちが分かりますが、
とにかく授業で習った英語を使って文章を書くと意味がちゃんと伝わるはずです。

変数の命名も同じだと思います。
知っている単語や規約から始めて、そして先輩のコードやオープンソースのコードを見て、良い命名の仕方を学んでいけると思います。プログラミングの専門用語もあるので、オープンソースのプログラムを読んでみると、どんな単語がよく使われているか、何があんまり使われていないかが分かってくると思います。

かっこよくて長い英語とかじゃなくて、知っている単語やフレーズから始めて可読性を重視しましょう。 Simple is best.

ただ、省略する時は気をつけましょう。
こんなコードを見たことはありませんか？

```ruby
rlts = db.search(type: "foo")
rlts.each { |r| r.type.upcase! }
```

「何、このrlts？」となるようなコードにならないように気をつけましょう。
こう書くとしちょっと長くなりますが、意味が伝わるのでより良いです。

```ruby
results = db.search(type: "foo")
results.each { |result| result.type.upcase! }
```

「db」がよく出てくるのでそのまま省略しても違和感はありません([railsからの例](https://github.com/rails/rails/blob/f481353150c100dbd944d5aa84f2480264cd723c/activerecord/lib/active_record.rb#L214))。

「db」とか以外の場合は変数が短すぎると、分かりにくい時もあるので気をつけましょう。自信がない時は、そのまま英単語を書きましょう。

また、略を書きたい時は、その定義をする時に意味を説明するコメントを書くか、周りのコードから元の名前を簡単に推測できるように書きましょう。
下記は[railsからの例](https://github.com/rails/rails/blob/f481353150c100dbd944d5aa84f2480264cd723c/activerecord/lib/active_record/associations.rb#L2069-L2070)です。

```ruby
# 1行目でhas_and_belongs_to_manyが書いてあるので、
# 2行目からhabtmを書いても問題はない。
def has_and_belongs_to_many(name, scope = nil, **options, &extension)
   habtm_reflection = ActiveRecord::Reflection::HasAndBelongsToManyReflection.new(name, scope, options, self)
   # ...
end
```

また、[Kaminariからの例](https://github.com/kaminari/kaminari/blob/554f588cb54736d014099d2be60e6d41b3c93838/kaminari-core/lib/kaminari/helpers/paginator.rb#L132-L139) (メソッド名の「rel」はrelationshipの略です)

```ruby
# relationship with the current page
def rel
  if next?
    'next'
  elsif prev?
    'prev'
  end
end
```

# 5. その他のオープンソースからの例

[carrierwave](https://github.com/carrierwaveuploader/carrierwave?tab=readme-ov-file#getting-started)のドキュメントからの例
```ruby
uploader.store!(my_file)
```

[Fakerからの例](https://github.com/faker-ruby/faker/blob/245812bbce487bcee08d5f251c327546d87e6091/lib/faker.rb)：「動詞 + 目的語」という形

```ruby:faker/lib/faker.rb
def shuffle(list)
def letterify(letter_string)
def fetch(key)
def resolve(value)
```

また[railsからの別の例](https://github.com/rails/rails/blob/f481353150c100dbd944d5aa84f2480264cd723c/activerecord/lib/active_record/migration.rb)

```ruby:rails/activerecord/lib/active_record/migration.rb
def write(text = "")
def announce(message)
def say(message, subitem = false)
def validate(migrations)
```

[friendly_idからの例](https://github.com/norman/friendly_id)

```ruby:friendly_id/lib/friendly_id/candidates.rb
def normalize(candidates)
def filter(candidates)
```

```ruby:friendly_id/lib/friendly_id/configuration.rb
def use(*modules)
def set(values)
```

[Capybaraからの例](https://github.com/teamcapybara/capybara/blob/master/lib/capybara/driver/node.rb)

```ruby
def trigger(event)

# 下記は「動詞 + 前置詞 + 名詞」なのですが、考え方が一緒です。
def drag_to(element, **options)
def scroll_to(element, alignment, position = nil)
```

# 振り返り
一番大事な項目は次の２つだと思います
1. プログラミングの書き方がますます英文らしく変わっていく現実の波に乗りたい
2. 知っている単語やフレーズから始めて、シンプルかつ文章らしいコードを書くと可読性が上がりますし、仕事の効率につながります

「私はできる！」と自分から言うのは難しいかもしれませんが、たくさんの日本人は結構いい英語でコードを書いています。みんなと分かりやすい言い方を共有したりして、拡張しやすいコードを書いていきましょう。

Do your best, and please enjoy programming in English!