[Ruby] Ruby コーディングアンチパターン
WEB+DB PRESS Vol.86 の memo.
WEB+DB PRESS Vol.86
posted with amazlet at 16.07.11
結城 洋志 沖元 謙治 足永 拓郎 林 健太郎 大竹 智也 内田 誠悟 伊藤 直也 中山 裕司 hiroki.o 泉水 翔吾 佐藤 太一 高橋 俊幸 西尾 泰和 舘野 祐一 中島 聡 橋本 翔 はまちや2 竹原 麻植 泰輔
技術評論社
売り上げランキング: 218,454
技術評論社
売り上げランキング: 218,454
Contents
コーディングアンチパターン
引数を囲む括弧を省略しない
# Bad
do_something foo, bar
# Good
do_something(foo, bar)
# Exception
require 'path/to/file'
条件節での代入を避ける
# 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 を使わない
# 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!')
クラス変数を使わない
クラス変数を使わず「クラスインスタンス変数」を利用する。
# Bad
class Foo
def self.value=(value)
@@value = value
end
end
# Good
class Foo
def self.value=(value)
@value = value
end
end
クラス変数はそれが定義されたクラスだけでなく、そのサブクラスとも共有される変数であるため。
スーパークラスとサブクラスで共有されるが、このような挙動がほしいケースはあまりない。
ensure 節に return を記述しない
例外発生時に例外がもみ消されてしまう。
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 節の最後に戻り値を記述する。
未使用のローカル変数
アンチパターンではないが。
変数名を _
で始めることで「これは宣言したが未使用な変数である」ということを表明する慣習がある。
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
複数行の文字列の連結
文字列リテラルを連結するいくつかの選択肢。
# 行末に \ を使う
'foo' \
'bar'
# String#+ メソッド
'foo' +
'bar'
# String#<< メソッド
'foo' <<
'bar'
それぞれメリット・デメリットがあるが、どれを使っても良い。
複数行のメソッドチェインのドット位置
メソッド呼び出しの .
をどう置くか。
# 改行前の行末に置く
string.downcase
.gsub(' ', '_')
# 改行後の行頭に置く
string.downcase.
gsub(' ', '_')
それぞれメリット・デメリットがあるが、プロジェクトメンバーの嗜好に合うものを使う。
まとめ
まとめ部分。
Ruby Style Guide と RuboCop について触れられている。
補足