fv17の日記

Webエンジニアの備忘用ブログです。主にWeb界隈の技術に関して書いています。

RuboCop Airbnbの導入方法

RailsにRubocop Airbnbを導入する。

設定方法

Rubocop AirbnbGithubのInstallationに導入方法が書かれている。

  • Gemfileに gem 'rubocop-airbnb' の一文を追加
  • Gemfileと同じディレクトリに .rubocop.yml と .rubocop_airbnb.yml を新規作成

ただし、.rubocop.yml は公式Docに記載されている通りのままだと下記の現象が起きるため、対応が必要

.rubocop_todo.ymlが無いよと怒られる

公式docでは .rubocop.yml 作成時に .rubocop_todo.yml と .rubocop_airbnb.yml を inherit するように記載しているが前者はいらない。.rubocop_todo.ymlは「Rubocopでエラーとなっているが後で対応すること」を記載するファイルであり、必要になるまで不要。

rails newコマンド打ったばかりのコードに対して色々エラーが出る

configやdbなどのファイルに対してエラーが出る。特に問題ないはずなので下記に示した方法で除外する。vendorフォルダとかもチェックする必要ないので、状況に応じて除外対象に追加。

.rubocop.yml

inherit_from:
  - .rubocop_airbnb.yml

AllCops:
  Exclude:
  - 'bin/*'
  - 'config/**/*'
  - 'db/**/*'
  - 'spec/spec_helper.rb'

rubocopの実行

bundle exec rubocop -R -D

-Rオプション

--railsの省略形で、railsに特化したCopが実行される。毎回付けるのが面倒な場合は、.rubocop.yml で下記のように設定すればOK

AllCops:
  RunRailsCops: true

-Dオプション

エラーメッセージにおいて、各Copの名称が表示されるようになる。デフォルトでtrueとのことなので付けなくても良いかも(未検証)

Rubocop実行時の様々なオプション(フラグ)

様々なオプションがあるので、下記における「Other useful command-line flags」で確認できる
Basic Usage - RuboCop: The Ruby Linter that Serves and Protects

正規表現 - 肯定の先読み・後読みなどの復習

下記の復習用

qiita.com

投稿してから気づいたが、上記の記事の「まとめ」読めばいいじゃん...
まぁ写経がてら学べたからよしとしよう。

\b 単語の境界

「単語の境界」を意味する。下記から英単語「ear」を抽出したい時に、「\bear\b」とすることで「hearing」にマッチせず「ear」のみ抽出できる。

ear is the organ of the sense of hearing.

肯定の後読み・先読み

肯定の後読み (?<=abc) abcの「直後の位置」から
肯定の先読み (?=abc) abcの「直前の位置」において
否定の後読み (?< !abc) abc以外の「直後の位置」から
否定の先読み (?!abc) abc以外の「直前の位置」において

< !の間のスペースは不要。はてな記法に対応するため空けているだけ。

後方参照

キャプチャした文字列を、正規表現内部で参照する技のこと。

<a href="http://google.com">http://google.com</a>

下記の正規表現のように、\1や\2などと参照できる。

<a href="(.+?)">\1<\/a>

| または

/','|':'/

Railsのバリデーションにおける^ &は\A \zを使うこと

validates :phone_number, format: { with: /\A\d+-\d+-\d+\z/ }

^ &はあくまで「行の」先頭と末尾。そのため、複数行入力に対応できずセキュリティ的に危険。
上記の理由で、「文字列の」先頭と末尾を意味する\A \zを使うべし。
なお、\Zは文字列の末尾の改行文字を許可してしまうので\zとする。

\ でエスケープ

[abc] という文字列にマッチさせたい場合、\[abc\] とすれば良い
同じように、test.rbという文字列にマッチさせたい場合、test\.rb と\.にしないと任意の1文字と判断されるので注意。

Rubyにおけるprivateの仕様が他言語と違う理由

メタプログラミングRuby」に「privateの本当の意味」というコラムがあるのだが、そもそもJavaなどの言語と仕様が違う理由は何か?、なぜJavaのようなシンプルな設計となっていないのか?、設計思想は?、と気になったので調べてみた。


ズバリの記事があった。Ruby界隈でググってると良く目にする"てぃーびー"さんの記事。
qiita.com

RSpec - マッチャ一覧

参照は下記。本記事にないマッチャはいずれかを参照すれば見つかる。

== を検証する eq

expect(actual).to eq(expected)

比較を検証する be >

expect(actual).to be >  expected
expect(actual).to be >= expected
expect(actual).to be <= expected
expect(actual).to be <  expected

正規表現、文字列との一致を検証する match

expect(actual).to match(/expression/)

true、falseを検証する be_truthy

expect(actual).to be_truthy
expect(actual).to be true

expect(actual).to be_falsy
expect(actual).to be false

expect(actual).to be_nil
expect(actual).to_not be_nil

配列の要素の同値性を検証する contain_exactly

配列要素の順番は問わない。match_array はエイリアスメソッド。

expect([1, 2, 3]).to contain_exactly(2, 3, 1)
expect([:a, :c, :b]).not_to contain_exactly(:a, :c )

expect([1, 2, 3]).to match_array [2, 3, 1]
expect([:a, :c, :b]).not_to match_array [:a, :c]

配列に指定した要素を含んでいるかを検証する include

include?を持つオブジェクトに使えるため、arrayだけでなくstringやhashなどに対しても使える。

# Array
expect([1, 2]).to include(1)
expect([1, 2]).to include(1, 2)
expect([1, 2]).not_to include(17)

# String
expect("a string").to include("a")
expect("a string").to include("str")
expect("a string").to include("str", "g")
expect("a string").not_to include("foo")

# Hash
expect(:a => 1, :b => 2).to include(:a)
expect(:a => 1, :b => 2).to include(:a, :b)
expect(:a => 1, :b => 2).to include(:a => 1)
expect(:a => 1, :b => 2).to include(:b => 2, :a => 1)
expect(:a => 1, :b => 2).not_to include(:c)

Ruby - 文字列操作に関するメソッド一覧

=~

todo

match

todo

scan

Stringのメソッド。
正規表現のパターンとマッチする部分を文字列からすべて取り出し、配列にして返す。

'123 456 789'.scan(/\d+/)
# => ['123', '456', '789']

参考 : scan (String) - Rubyリファレンス

split

Stringのメソッド。
引数の文字列あるいは正規表現を区切り文字として分割し、配列にして返す。

'ruby,python,java'.split(',')
# => ['ruby', 'python', 'java']

'sqlite, mysql  , postgresql'.split(/\s*,\s*/)
# => ['sqlite', 'mysql', 'postgresql']

参考 : split (String) - Rubyリファレンス

grep(obj)

「obj == 要素」を試し、trueだった要素を配列にして返す。

["cat", 123, "#dog", "mouse"].grep(/^[A-Za-z]+$/)
# => ["cat", "mouse"]

参考 : grep (Enumerable) - Rubyリファレンス

gsub

todo

slicce

todo