ruby,railsコーディング規約とかチーム開発での運用について@五反田.rb

## 好きなコーディング規約
- Move Model Logic into the Model(Rails Best Practices
)
    - 正しいレシーバーを意識させてくれる
- Metrics/CyclomaticComplexity(rubocop) 
- Metrics/BlockLength(rubocop)
- Metrics/ModuleLength(rubocop)
    - 小さいものを組み合わせてプログラムを組み立てることを意識させてくれる
- railsの幾つかの非公開apiでprivate methodに`_`prefixをつけるところがあるらしい、統一はされてない(オブゼクト指向設計ガイドのコラム)
    -　private_methodの呼び出し側で、public　methodでprivate_methodを利用して実装することが意識しやすい
    -　publicなメソッド(インターフェース)を最小にして組み立てて行くことで、影響範囲を小さく意識できると思う。

![image](https://qiita-image-store.s3.amazonaws.com/0/31015/6269b62f-24d0-1e88-848b-8593a0224185.png)


rubocopのを入れておくと、自然とrubyぽい書き方になっていく気がする。

## 公開されているスタイルガイド読むだけでも勉強になる
- https://github.com/fortissimo1997/ruby-style-guide/blob/japanese/README.ja.md
- https://github.com/airbnb/ruby/blob/master/README.md
- https://github.com/moneyforward/ruby-style-guide

自分はスタイルガイドを読んで、コード上での文字列の分割ほうほうとかしりました。

```ruby:sample
str = "hogehoge"\
      "gehogeho"
```



## 規約を取り入れることでの実感
- 人間だよりにすると基本的に守られない(仕組みや、運用方法のPDCA必要)
- 規約で統一されていると読みやすいし、間違いに気付きやすい
    - コード書くより、読む時間の方が長い
    - 式が値を返すことを意識して書くやつを導入、必要ない`if`分のネストが見つかったりしたことがあった。

```ruby:sample
#bad
  if fuga
    @hoge = "fuga"
  else
    if piyo
      @hoge= "piyo"
    end
  end

#規約の自動変換後、ネストおかしくないか？
@hoge =
  if fuga
    "fuga"
  else
    @hoge =
      if piyo
        "piyo"
      end
  end

#good 手動で少し修正
@hoge =
  if fuga
    "fuga"
  elif piyo
    "piyo"
  end
      
```


## コーディング規約を守るための仕組み、サービス
### 見える化(ゆるくとりしまる)
- [sideci](https://sideci.com/)
    - githubのPullRequestに対してコメントしてくれる
    - 豊富なチェック項目がある
        - Rails Best Practices
        - rubocop
        - reek(英語力なさすぎて、きつい)
        - 他
    - githubのレビューの仕様が変わって、指摘が多いと若干PullRequestが見づらくなる（コメントが消えなくなった？）
    - ブラウザ更新しないとコメントが反映されないのか、無視してたまにマージされてしまう
    
### 厳しく取り締まる方法
- overcommit等を使いコミットできなくする
- circleciでcommit statusを失敗にさせる
    - 流石に、commit statusが赤のままマージする人はいないので、ストッパーになっている
    - Gem `rubocop-junit-formatter`を導入して、circle.yamlファイルを以下のような設定すると見やすくなる

```yml:circle.yml
test:
  pre:
    - bundle exec rubocop -r $(bundle show rubocop-junit-formatter)/lib/rubocop/formatter/junit_formatter.rb --format RuboCop::Formatter::JUnitFormatter --out $CIRCLE_TEST_REPORTS/rubocop/junit.xml:
        parallel: true
        files:
          - app/**/*.rb
          - lib/**/*.rb
          - config/**/*.rb
          - spec/**/*.rb
          - script/**/*.rb

```
![image](https://qiita-image-store.s3.amazonaws.com/0/31015/1787e917-5f0b-37f6-3b14-9efba927504c.png)

### 楽する
- guard-rubocop
- エディターの機能拡張
- IDEの自動フォーマット等

## 素早く導入する時のポイント、運用方法
### 前提条件
- こまめにリリース
- ciで担保されている

### rubocopを既存のプロジェクトになじませていく流れ
- rubocop --auto-gen-config
    - todo作成
    - --auto-correctで直せる規約から少しずつ直してリリースする
        - github pull requestは25ファイル以上含めるとdiffが見えないから、一回のリリースで最大25個までにした。
        - こまめにリリースして、長いスパンで改善していく。
        - 自動修正は基本的に、修正前と動作は同じになっているはず。
    - 残った規約も一つづつ対応
    - 新しくルール違反させないためには、既存の違反を例外のコメントで囲って、ルールを有効にし、あとから修正するようにすればいい。
        - 新しくルール違反させないためには見える化等が必要(sideci,circleci等)

### 規約の運用方法
- 1人にまかせてある程度決めてしまう(こう言う整理整頓が好きな奴がいればベスト)
    - 独裁の方がスピード間がある、民主主義は基本的に話が進まない
    - あくまでスタートが独裁だとスピードがでるという話
    - 決め打ちではなくて、問題や新しい観点があればつど見直す
    - 前より良くしようということが大切だと思う、いつでも見直す
    - ちゃんとした理由が必要
- 導入する際のメリットがなければ入れない
- 複数選択肢がある場合、以下の順番で決めるのがいいのではないか
    - メリットが大きい方を取る
    - 既存のコードの修正が少ない方を取る
    - 多数決
    - ルーレット・じゃんけん
- やっちゃいけないこと
    - おれはこう書くのが好きだから絶対ゆずりたくない
        - ちゃんと導入すうるメリットを考えよう
- 機械的な仕組みが必要
    - こういうふうに書くんだよってのは、機械的にチェックする仕組みがないと守られにくい


## こういうのあったらいいなぁ
- オリジナルの規約を柔軟に取り入れる仕組みがあるといいかなと
    - botとかgithub apiとか使えばできるのかなぁと
    - 規約のチェックは[これ](http://qiita.com/tos-miyake/items/f28206770b91b1222e54)で行けそう
- リファクタリングのポイントを抑えて指摘
    - reekがこれに当たるのだろうか？
- publicメソッドはyardoc書きたい