株式会社クイックのWebサービス開発blog

HAPPYなエンジニア&デザイナーのブログです

「リーダブルコード」等、コーディング規則に関するまとめ

こんにちは。 新人エンジニアの五所です。

現在は便利ツールの作成や業務システムの手直しなどを行っています。

私は文系大学出身なのですが、大学2年の頃からプログラミングを始めました。 そこからプログラミングにはまり、今はエンジニアのはしくれです。

とりあえずの目標は、誰が読んでも理解しやすいようなコードを書くことです。

良いコードを書きたい

私はプログラミングを完全に独学で学んできたので、あまり人に見せることを想定していませんでした。

ただ、自分で後で見返した時に「なぜこう書いたんだろう?」「何をしているんだろう?」という箇所が多数ありました。明日の自分は今日の自分とは違うのです。

自分でもわからないのだから、他の人が理解するのは不可能だろう。ましてや再利用したりバグ修正などするくらいなら、最初から作りなおした方がましかもしれません。

このような問題意識を持ち、「リーダブルコード」という本を読みましたので、自分の経験および自戒も含めてそのまとめをさせて頂きます。

  • 明日からできそうなことだけ書いてます。
  • 言語はRubyで書いてます。

コードをなるべく書かないで済ます

いわゆる「車輪の再発明はしない」というやつですね。 他に使えるライブラリやツールが無いか調べることから始め、無かったら作るというスタンスでいたいものです。

数々のコマンドを組み合わせないとできないと思っていたことが、ライブラリ一つで解決することも多々あります。

縦の線を揃える

単純ですが、ぐっと見やすくなります。

# NG
name = '山田太郎' # フルネームで記述
address = '東京都港区 赤坂2-11-7' # 郵便番号は除く 

# OK
name     = '山田太郎'                # フルネームで記述
address  = '東京都港区 赤坂2-11-7'   # 郵便番号は除く

ちゃんとした名前をつける

本当に使い捨ての場合(2つの値を入れ替える等)を覗いて、tmpやretvalなどの名前はつけない方が幸せになれます。 下記の例ではtmpが何のことだかわかりません。

# 配列の値を2乗して合計する
def sum_sqrt(values)
    tmp = 0
    values.each do |value|
        tmp += value ** 2
    end
    return tmp
end

下記の例では、sum_sqrtが2乗した合計と分かるので、バグなどがあれば見つけやすいです。

# 配列の値を2乗して合計する
def sum_sqrt(values)
    sum_sqrt = 0
    values.each do |value|
        sum_sqrt += value ** 2
    end
    return sum_sqrt
end

具体的な名前を付ける

変数や関数の名前は、多義語は避け、なるべくその働きを明確に表している言葉を使いましょう。

悪い例 良い例
make_file create_file, write_file, ...
get_data download_data , fetch_data, read_file, ...
check check_length, is_writable, validate, ...

自分の考えを残しておく

コメントはただコードの内容を記載するだけではなく、コーディング中の自分の思考の痕跡を残す役割もあります。

下記のようなルールを作っている方が多いようです。

記法 典型的な意味
TODO: あとで手をつけなければならないもの。汚いロジック、突貫工事、重複した箇所など・・・。
FIXME: 既知のバグがあるコード。とりあえずこう書いておかないと忘れる。
HACK: あまり綺麗ではない解決策。無力の念を伝える。
XXX: 危険!大きな問題がある。
# TODO: 関数fetch_dataと重複した処理があるのでまとめたい。
# FIXME: 配列に重複がある場合の処理が不足。

コメントは簡潔かつ正確に

情報を短い文章に詰め込むことを意識します。

# file_nameという名前のファイルが存在するかどうかで、処理を分ける。
if !file_exists?(file_name) then

file_nameがファイル名を表すことは自明ですし、「処理を分ける」というのが歯切れが悪い言い方です。 下記の方が簡潔です。

# ファイルが存在する場合、処理をスキップする。
if !file_exists?(file_name) then

「処理をスキップする」という新しい情報も加わっています。

みんなが知らない略語は使わない

プログラマーであれば、 str=文字列、int=整数、i18n=internationalization、tmp=一時的ファイル などは知っているはずです。こうした略語を使うのは簡略化になるので良いのですが、下記のような略語は読み手を混乱させます。

u_a  = 'OS X safari'  # ユーザーエージェント
PMK  = 'id'           # プライマリーキー
def e_handler(e)      # エラーハンドラー

errorをeに省略したところで、簡略化につながるとは思えません。

たとえそこそこ長い名前があったとしても、エディタの動的略語展開を使えば良いだけなので、読みづらくなるくらいなら省略しないのが無難でしょう。

以上、少しだけですが、明日からできそうなことを書いてみました。

www.amazon.co.jp