[Ruby] Ruby コーディングアンチパターン
WEB+DB PRESS Vol.86 の memo.
[markdown]
技術評論社
売り上げランキング: 218,454
## コーディングアンチパターン
### 引数を囲む括弧を省略しない
“`ruby
# Bad
do_something foo, bar
# Good
do_something(foo, bar)
# Exception
require ‘path/to/file’
“`
### 条件節での代入を避ける
“`ruby
# Bad
if result = do_something
p result
end
# Good
result = do_something
if result
p result
end
# Case by case
if (result = do_something)
p result
end
“`
代入式と条件式を分けると冗長となる場合はこの限りで無い。
### and, or, not を使わない
“`ruby
# Bad
result = (1 and 2)
fetch_something or raise ‘Failed fetching!’
# Good
result = 1 && 2
fetch_something || raise(‘Failed fetching!’)
fetch_something || (raise ‘Failed fetching!’)
“`
### クラス変数を使わない
クラス変数を使わず「クラスインスタンス変数」を利用する。
“`ruby
# Bad
class Foo
def self.value=(value)
@@value = value
end
end
# Good
class Foo
def self.value=(value)
@value = value
end
end
“`
クラス変数はそれが定義されたクラスだけでなく、そのサブクラスとも共有される変数であるため。
スーパークラスとサブクラスで共有されるが、このような挙動がほしいケースはあまりない。
### ensure 節に return を記述しない
例外発生時に例外がもみ消されてしまう。
“`ruby:test.rb
require ‘fileutils’
# Bad
def process(should_success)
puts ‘Creating tmp directory’
Dir.mkdir(‘tmp’)
raise ‘error!’ unless should_success
ensure
puts ‘Removing tmp directory’
FileUtils.rm_rf(‘tmp’)
return ‘succes’
end
# Good
def process(should_success)
puts ‘Creating tmp directory’
Dir.mkdir(‘tmp’)
raise ‘error!’ unless should_success
‘success’
ensure
puts ‘Removing tmp directory’
FileUtils.rm_rf(‘tmp’)
end
return_value = process(ARGV.first == ‘true’)
puts “Return value: #{return_value.inspect}”
“`
rescue 節を使って例外を補足し、その例外を投げないまま戻り値を返したい場合でも、ensure 節ではなく rescue 節の最後に戻り値を記述する。
### 未使用のローカル変数
アンチパターンではないが。
変数名を `_` で始めることで「これは宣言したが未使用な変数である」ということを表明する慣習がある。
“`ruby
scores = {
‘foo’ => 93,
‘bar’ => 89,
‘baz’ => 98
}
sorted_scores = scores.sort_by { |_name, score| score }
“`
## 一貫性を保つためのスタイル
### Enumerable モジュールのメソッドの別名
同じ動作で別名が付けられているもの。
プロジェクト内でどちらを利用するか決めておく。
– map/collect
– reduce/inject
– find/detect
– find_all/select
### 複数行の文字列の連結
文字列リテラルを連結するいくつかの選択肢。
“`ruby
# 行末に \ を使う
‘foo’ \
‘bar’
# String#+ メソッド
‘foo’ +
‘bar’
# String#<< メソッド
'foo' <<
'bar'
``` それぞれメリット・デメリットがあるが、どれを使っても良い。 ### 複数行のメソッドチェインのドット位置 メソッド呼び出しの `.` をどう置くか。 ```ruby
# 改行前の行末に置く
string.downcase
.gsub(' ', '_')
# 改行後の行頭に置く
string.downcase.
gsub(' ', '_')
``` それぞれメリット・デメリットがあるが、プロジェクトメンバーの嗜好に合うものを使う。 ## まとめ まとめ部分。
Ruby Style Guide と RuboCop について触れられている。 > * [bbatsov/ruby-style-guide: A community-driven Ruby coding style guide](https://github.com/bbatsov/ruby-style-guide)
> * [bbatsov/rubocop: A Ruby static code analyzer, based on the community Ruby style guide.](https://github.com/bbatsov/rubocop)
補足
> * [bbatsov/rails-style-guide: A community-driven Ruby on Rails 4 style guide](https://github.com/bbatsov/rails-style-guide)
[/markdown]