プログラミング

[Vue.js] 俺的ベストプラクティス+バッドプラクティス

Vue.js

Vue.jsを1年半ぐらい使ってきて、それなりに知見が溜まってきたので、それらを俺的ベストプラクティスとして吐き出してみようと思う。巷にあふれるVueのベストプラクティスってv-forに:key付けようとか、お作法的な話ばかりで、あまり実践的な内容は見かけないのが記事を描き初めたきっかけ。というわけで内容的にはややマニアックで、Vue初心者にはちょっと難しいかもしれないのでそこはあしからず。なお対象はVue 2で、Composition APIは使ってないのであしからず。あとTypescriptでも使ってない。 ...続きを読む

rubocop + pre-commitで規約違反のコードをコミットできないようにする

rubocopはrubyの静的コード解析を実行してくれる便利なgem。例えば、ソースコード内の残念なメソッド名を発見してくれたり、1メソッドの行数を制限できたりする。解析内容は多岐にわたるので、ぜひ公式ドキュメントを参照あれ。

一方pre-commitとは、gitコミットをフックして何らかのアクションを実行してくれるgem。末尾の空白を検知したり、Javascriptのconsole.logや、pryのbinding.pryがソース内に残っていないかなどチェックできる。こいつが標準でrubocopもサポートしているので、これらを組み合わせると、規約違反のコードが含まれている場合にgit commitできないようにすることができる。

セットアップ

bundle + railsという環境を想定すると、Gemfileは以下のようになる。

📄Gemfile
group :development do
  gem 'rubocop', require: false
  gem 'pre-commit', require: false
end

bundle installした後に、pre-commitをインストールする必要がある。

📄config/pre_commit.yml
$ bundle exec pre-commit install

git-hookは新しいshプロセスで動くので、pre-commitはbundler経由で実行させるよう、gitの設定を施してやる必要があります。

$ git config pre-commit.ruby "bundle exec ruby"

これにて導入は完了。

pre-commit

pre-commit listコマンドで各checkの利用状況が確認できる。

$ bundle exec pre-commit list
Available providers: default(0) git(10) git_old(11) yaml(20) env(30)
Available checks   : before_all ci closure coffeelint common console_log csslint debugger gemfile_path go jshint jslint json local merge_conflict migration nb_space pry rails rspec_focus rubocop ruby ruby_symbol_hashrockets scss_lint tabs whitespace yaml
Default   checks   : common rails
Enabled   checks   : common rails
Evaluated checks   : tabs nb_space whitespace merge_conflict debugger pry local jshint console_log migration
Default   warnings : 
Enabled   warnings : 
Evaluated warnings :

Available checksが利用できるチェックの一覧。Enabledが現在利用しているチェックである。上記ではcommonとrailsというチェックがなされている。この2つのチェックに含まれる個々のチェックはEvaluated checksに記述されている。要するに、これらが実際に実行されるチェック。このあたりは公式サイトとかこのあたりを参考にしてほしい。

デフォルトではrubocopを利用するようにはなっていないので、設定を変更しよう。

$ bundle exec pre-commit enable yaml checks rubocop

yamlと指定しているのは、設定をyamlファイルに書き出すということ。railsディレクトリ内で実行すると、config/pre_commit.ymlというファイルが出来上がっているはずだ。

---
:checks_remove: []
:checks_add:
- :rubocop

今後はこのファイルを直接編集してもよい。ちなみに、先のyamlと指定をgit にするとgitのグルーバル設定にすることができる。プロジェクトで配布する場合はyamlにしておいた方がよい。またrubocopチェックに引っ掛かってもエラーではなく警告にとどめておきたい場合は、checksではなくwarningsを指定する。

rubocop

rubocopでチェックできる内容は多岐に渡り、中には「こんなんもんいらねー」的なチェックもある。何をどうチェックするかの設定をyamlファイルに記述しておくことができる。ルートディレクトリに.rubocop.ymlというファイルを作成すればよい。以下は私が使用している設定。

📄.rubocop.yml
AllCops:
  RunRailsCops: true
  Exclude:
    - bin/**/*
    - config/boot.rb
    - db/schema.rb
    - script/**/*
    - tmp/**/*
    - vendor/**/*

# 1クラスの行数を200行以下に制限する
Metrics/ClassLength:
  Max: 200

# 1行の文字数を制限しない
Metrics/LineLength:
  Enabled: false

# 1メソッドの行数を制限しない
Metrics/MethodLength:
  Enabled: false

# 日本語コメントを許す
Style/AsciiComments:
  Enabled: false

# ファイル冒頭にコメントを書かなくてもよい
Style/Documentation:
  Enabled: false

# class Hoge::Fooのような記述を許す
Style/ClassAndModuleChildren:
  Enabled: false

どんなチェックがあって何を意味しているのかはenabled.ymlのソースを見ればよい。ruby-style-guideへのリンクも記述されているので辞書として利用できる。

手動でrubocopを実行するにはコマンドを叩けばよい。-Dオプションを付けると、引っ掛かったチェック名を表示してくれるのでお勧め。

📄.git/hooks/pre-commit
$ bundle exec rubocop -D

これにてgit commitする度にチェックが走り、エラーがあったらコミットさせてくれないという理想的自虐的環境ができあがった。

既存のプロジェクトに適用させる場合

おそらくデフォルトのルールでrubocopを実行するとエラーまみれになると思う。rubocopでは、必要なチェックなのか吟味しながら少しずつエラーを無くしていくというアプローチが取れるようになっている。このサイトが詳しい。

zsh + rbenvな環境でpre-commitが動かない場合

2016/07/19 追記:現在では公式githubに載っているように、次のコマンドを実行すれば動くようになっています。

$ git config pre-commit.ruby "bundle exec ruby"

—–

pre-commit installした際に自動生成される.git/hooks/pre-commitではzsh+rbenvという環境上では動かない(少なくとも私の環境ではgit commit時にエラーになった)。思いっきり書き換えてしまうことにする。

#!/bin/zsh
source ~/.zshrc

bundle exec ruby -rrubygems -e '
  begin
    require "pre-commit"
    true
  rescue LoadError => e
    $stderr.puts <<-MESSAGE
pre-commit: WARNING: Skipping checks because: #{e}
pre-commit: Did you set your Ruby version?
MESSAGE
  false
  end and PreCommit.run
'

参考

技術力が低いプログラマにありがちな7つのこと

僭越ながら、思いの丈を綴ってみた。

1. 正規表現を知らない

今どきVBAでも使えるのに、何で覚えようとしないのか。あれだけ便利かつ言語間で共通して使える技術は他に無いのに。こういう奴に限って「え〜!? メールアドレスの書式チェックですかあ? あれって結構大変なんですよねー」とか言っちゃって困る。

2. 正規表現を見ると「なにその暗号? 誰にでも分かるコードを書かないと」と不機嫌になる

もはや正規表現は「誰にでも分かる」に該当していると思う。・・・違うの??

3. 「誰にでも分かるコードを書かないとね」と言って、forとifのみで物事を解決しようとする

この手の人たちは「誰にでも分かる」の意味を履き違えてると思うな。別にシンプルな制御文のみを使えって意味じゃない。『リーダブル・コード』でも読んだ方がよい。

4. 1行メソッドにケチをつける

「ねえねえ、これ見てよ。たった1行の処理なのにわざわざメソッドにしてるんだよ!  笑えねぇ?」なんて言ってはいけない。可読性を上げるためや委譲する場合など、1行メソッドを実装する機会はしょっちゅうある。

5. コピペにためらいが無い

DRYと聞くとコーナンのDIYコーナーが頭に浮かぶぐらいなので。CTRL+C からの CTRL+Vは超早い。

6. マージをしたことが無い

もしくはマージに怯える。フォルダでバージョン管理歴が長いせいか、git等によるバージョン管理に弱い人が多い。

7. そもそも意識が低い

一応「プロ」のはずなのに、「技術に興味が無い」とあっけらかんと言う。仮にお医者さんがこんなこと言えるだろうか・・?

まだまだありそうだけど、今日はところはこの辺で。

プログラミング学習は流行るのか

最近、プログラミングを学ぶということに注目が集まっている気がする。

オバマ、ジョブズ、ザッカーバーグが語る「プログラミングを学ぶ必要性」とは【動画紹介】

自分もプログラマーなので、そういった機運が高まっていることは素直に嬉しい。同業者のみでしか共有できなかったあんな話やこんな話が、普通の友人との酒の肴になるなんて、素晴らしいことじゃないか。ユーザー側にも技術的素養を持っていただくことは、ソフトウェア開発における甲乙双方にメリットを産むと思う。そんなわけで、ぜひともみなさんにプログラミングを学んで欲しい。

同時に、とある疑問が頭の中をよぎったのだが・・そもそもプログラミング学習なんて流行るのかな?

そこで自分なりに三日三晩充分な睡眠と食事と共に考え抜き、たどり着いた結論は・・・

プログラミング学習は流行らない

んじゃないかということだ(我ながら悲しい)。もちろん、学校教育の中でプログラミングが必須になるという状況は、将来的にあり得ると思う。でも、街の随所でプログラミング塾が散見されたり、電車の中でええ歳したサラリーマンが『オフィスで役立つ! ExcelVBAテクニック100選!』たる分厚い本を読んだりする状況にはならないと思う。

なぜか? 理由は全部で108個ぐらいあると思うが、面倒なので一つしか書かない。それは、プログラミングすわなちソフトウェア開発は

目的までの道のりが想像以上に長い

ということである。これはソフトウェアが目に見えないものであることに起因すると考えている。

例えば、あなたは今、郊外にちょっと個性的なマイホームを建てたいと考えている。そのことを友人に話すと、

友人「いいじゃん。じゃあ、You自分で作っちゃいなよ!」 ・・・とはならない

それは、『家を建てるのはとても大変なこと』という共通認識をみんなが持っているからだ。

一方で、テレビで料理人が美味しいパスタの作り方を紹介していたとする。友人とその番組を見ていて、

友人「美味しそう! 今晩、ちょっと作ってみない?」・・・とはなりうる

もちろん、プロの料理人にかなわないとは分かっている。しかし、十分に美味しいと言えるパスタは素人でも作ることができるという認識も持ち合わせているはずだ。

ソフトウェアとは形を持たないゆえ、作成するのがどれぐらい難しいものなのか、未経験者にはなかなかピンとこない。最近の見渡すばかりのフリー(無料)な環境下において、その有り難みが薄れているような気がするが、そもそもソフトウェアとは、先の例でいうと『マイホーム』に近いと思う。つまり、作るのがとても大変な方。実用に耐えうる(「住める」「食べられる」)レベルのものを提供するとなると、それはそれは結構な時間と手間を要するもんなのだ。

しかもそのプロセスも実は結構退屈だったりする。しょーもないエラー処理だったり、年に1回しか陽の目を見ないような処理だったり・・・。たぶん、興味のない人にとっては苦痛以外何でもない。

つまり「これぐらいでできるっしょ?」と「実際にやらなければならない量」との間に想像以上のギャップがあるということ。軽い気持ちで山登りに出かけた結果「えー!まだ三合目!? もうヤダ、止める。」と続々下山・・・そんな感じの流れになるんじゃないかと勝手に想像している。

そもそも、過程を楽しめる人じゃないと続かない

ちゅうことなんだろう。しょーもないと思うエラー処理が多数あったなら、

「あーもう、こんなしょーもない処理何回も書きたくないなぁ。。 あ、そうか。だったら、ここをこうやって・・・」

→ 超絶リファクタリング → 悦に入る

とか。そういうの好きな人じゃないと続かない職業なんだろうと思う。だから、流行らないんじゃなかと。

とはいえ、やっぱりプログラミング学習、流行って欲しい。そして周りの人にややチヤホヤされて、「いや〜、俺もかれこれ10年やってるからねえ。俺も最初はさぁ・・」とか言ってみたい。というのはもちろん本当の話だが、それ以上にプログラミングって問題解決能力を高めてくれると思ってて、むしろそちらの方が大事なんじゃないかと思うわけで。