- レディーに悲しい思いはさせない。
- 食べ物や包丁を武器につかわない。
- 「読みやすくメンテナンスしやすいコードを書く」ことの価値観をチームで共有できる。
- コーディング規約という共通基盤を通して、プログラマーのスキルアップをはかることができる。
- 異臭をはなつ部分は、issueで議論しましょう。決まったものからこちらに移していきましょう。
- 場合によってはこの規約から外れることも時には重要であり、その際はなにかしらの説明を用意するようにしましょう。
- 見て読みやすく
- 読んで解りやすく
- スコープは適切に
- DRY(Don't Your Self)
- OCP(Open-Closed Principle)
- 一般的に多く使われているrubyistにまねる
- 変化を受け入れろ!
- 以下は Rails プロジェクトにおいてのルールである。基本的には Rails のルールにしたがうようにしましょう。
- RAILS_ROOT/app/views/layouts はレイアウトファイルのみを入れましょう。
- 全体を通して使用するレイアウトファイルは application.html.erb という名前で作成しましょう。
- コントローラにまたがる部分テンプレートは RAILS_ROOT/app/views/share に配置するようにしましょう。
- 名前は単なるラベルではなく、読み手に意味を伝えるべきものである。よって名前は意味のあるものであるべきです。命名する対象の変数のスコープの広さにに比例してわかりやすさ重視にしましょう。
#定数
Teinenpi #○
TNP #×
#クラス/モジュール名
class Joshikousei; end; #○
class Jk; end; #×
#メソッド名
def joshikousei?; end; #○
def jk? #×
#インスタンス変数
@joshikousei #○
@jk #△
#ローカル変数
@girls.each do |g| #○
g.joshikousei? #○
end
名前が長い場合に、入力の手間が増えるという問題があるが、それはIDEやエディタで対応できることなのでここでは問題にせずにいきましょう!
- クラス、モジュール名は、各単語の一文字めを大文字にし、'_'などの区切り文字は使用しません。
- TPPなどの略語の場合は全て大文字のままにしましょう(省略してるよーって意味が伝わるように)。
- 例外クラスでは特別な事情がない限り末尾に「Error」をつけましょう。
- よほどの意図がない限り、複数名を使用するはやめましょう。
#正解
NurseCall
TTPClient
AKBMember
OreOreError
#誤り
Nurse_Room
TPP_CLIENT
AKBMembers
CsvReader
- メソッド名は、全て小文字とし単語の区切りに_をつかいましょう。
- 真偽値を返すメソッド名は、動詞または形容詞に?を付けましょう。
- 破壊的なメソッドと非破壊的なメソッドの両方を提供する場合、破壊的なメソッドには!をつけましょう。
- それ以外で!を使用する場合は、メソッド作成者が利用者に対して、「あぶないぞー!!」っと意思表示したいときにつけましょう。
#正解
add_boy
pretty?
noripi?
dance
dance!
#誤り
addBoy
Add_Boy
is_noripi
was_noripi?
- 例外発生や、自己の状態を書き換える場合は、積極的にエクスクラメーションを使いましょう。
#例)
def make_hoge!
self.foo= "hoge"
end
メソッド名には、使うときに注意が必要だということを示すために、末尾に感嘆符をつけることができる。 この命名習慣は、オブジェクト自身を破壊的に書き換えるミューテータメソッドと下のオブジェクトのコピーに変更を加えたものを返すメソッドとを区別するために使われることが多い
- 動的にクラスメソッドを追加する等ではなく、あらかじめメソッド名がわかっている(ようは通常のクラスメソッド定義)の場合は、素直に、self.hogeを使いましょう
# 推奨
class Hoge
def self.hoge
end
end
#クラスメソッドが大量に発生した場合のみ推奨
class Hoge
class << self
def hoge
end
end
end
大量のクラスメソッドがある場合は、毎回selfはだるいので、こちらを使いましょう。また使う場合は、大量のクラスメソッドを一カ所にまとめるという効果もあります。
- クラス、モジュール名以外の定数名はすべて大文字とし、単語の区切りに'_'を用いるようにしましょう。
#正解
HONKY_TONKY_CRAZY_I_LOVE_YOU
- 変数名は全て小文字とし、単語の区切りに'_'を用いるようにしましょう。
- スコープが狭いループ変数には、i,j,k という名前、スコープが狭い変数名は、クラス名を省略したものを使用してもオッケー!!!
- 気持ちはとてもわかりますが、hogeとか、fooとかやめときましょう。
#(例:eo = ExampleObjext.new
tmp
local_variable
@instance_variable
$global_variable
- 公式だと _fieldsでAPIリファレンスがかかれている為、profile_fieldsにする。
- form_forの小要素の場合は_fileds, _formなどにする
# 悪い例
:f2, f3, p_fp_f
# いい例
profile_fields
- インデントは半角スペース2コ。ハードタブの使用は禁止です。あとで本当にきっついです。できる限りエディタでセットしておきましょう。
__if girl > 0
____if girl.pefurme? > 0
______puts "ferver!!!!!"
____end
__end
- 書き手は意図が伝わるようなコードを書くようにこころがけましょう。
- コーディング標準や規約に反する場合や、またプログラマー個人の意図がソースに介入している場所に限り、わかりやすいコメントを残すようにしましょう。
- プログラマーの腕のみせどころは、丁寧なコメントを多く書くことではなく、いかにわかりやすいコードを書くかです。よって、コメントを残す場合には「なにを」ではなく「なぜ」を書くようにしましょう。
- 代入に規制はないが、読みやすさを重視して書きましょう。
#正解
a = 'hoge'
a ||= 'moge'
a ||= true ? 'foo' : 'bar'
#誤り
a = 1 if a.nil? #×冗長なので×
#いい例
"#{i}さん、#{b}さん、#{a}さん"
#いい例)ダブルクオート
%(#{i}さん、#{t}さん、#{o}さん、"ITO")
#悪い例
i + "さん、" + b + ”さん、" + a + "さん"
- メソッドの定義の仮引数リストには括弧を付けるようにしましょう。
- 引数がない場合は、括弧をつけないようにしましょう。
#正解
def foo(x, y)
・・・
end
#誤り
def foo x, y
・・・
end
def foo()
・・・
end
- ruby2.0ではキーワード引数を使いましょう。
- html_optionsを渡したい場合等、全てがキーワード引数でカバーできるわけではないので、場合によっては使い分けをすること。
#2.0
def hoge( msg, limit: 10, offset: 10)
p msg
p limit
p offset
end
#1.9.3
def foo( msg, options=nil)
config = { limit: 10, offset: 10}.merge options
p msg
p config[:limit]
p config[:offset]
end
- ブロックは基本的にdo・・・endを使用しましょう。ただし1行の時は{}を使いましょう。
- またメソッドチェーンの場合も{}を使用しましょう。
#正解
foo(x,y) do
・・・
end
akb48.each{|a| a.dance!}
bar.map{|i| i.to_s}.each{|i| puts i}
#誤り
foo(x,y) {
・・・
}
foo.map do |i|
i.to_s
end.each do |i|
puts i
end
- if式のthenは省略しましょう。
- if !xのような場合は、unlessを使用しましょう。
- unlessのelseは、ifを使う。unlessは、ifのelseを使う。
- 条件が十分に簡単で、一行でかける場合は、修飾子として使ってもいい。
- 三項演算子も読みやすい範囲で使っていきましょう。
#正解
if self.perfume?
"yes i am."
else
"no i'm not."
end
# 1行で書けるときのみ
p 'present' unless hoge.blank?
puts "yes i am." if self.perfume?
puts self.perfume? ? "yes i am." : "no i'm not."
#誤り
if self.tashiro? then
puts "yes i m."
end
unless hoge.blank?
p 'present'
else
p 'blank'
end
puts "hoge" if foo && bar && baz && quux
#正解
case bust
when 80
puts "fum fum"
when 96
puts "hou hou"
end
#誤り
if bust == 80
puts "fum fum"
elsif == 96
puts "hou hou"
end
case bust
when 80 then
puts "fum fum"
when 96 then
puts "hou hou"
when 120 then
puts "haa haa"
end
while の do は省略しましょう。 while !x のような場合は、util x に置き換えましょう。
#正解
while cond
puts "puts is false"
end
util cond
puts "cond is false"
end
#誤り
while cond do
puts "cond is true"
end
また、無限ループには loop を使用しましょう。
#正解
loop do
puts "dance!dance!dance!"
end
#誤り
while true
puts "dance!dance!dance!"
end
- 例外発生の基本方針はそれが「異常事態」かどうかで判断するようにしましょう。
- 明示的に例外を発生させないとプログラムが異常終了してしまう場合に使用しましょう。
- 例えば、ActiveRecord での save!メソッドは使わず、save メソッドを使用しましょう(バリデーションに引っかかるのは例外ではなく、想定された動作なので)。
- ファイルの入出力は特別な事情がない限り、ファイルクローズなどの処理の記述忘れをしないためにも、ブロックを使いましょう。
#正解
open("sample.txt", "r") do |f|
puts f.gets
end
#誤り
begin
f = open("sample.txt", "r")
puts f.gets
ensure
f.close #忘れる可能性あり!!
end
- Rails アプリで使用する gems は RAILS_ROOT/Gemfileに記述すること。
- 特に指示がない限りバージョンは明記しておくこと。
- gem 'rails', '3.2.12'
- メタプログラミングをおこなう上では、運用/保守に入った際に他人が読んでもわかりやすいことを心がけるようにしましょう。
- superを使い、親のメソッドミッシングを呼び出すようにしましょう。
#正解
def method_missing(name)
if @attributes.key? name
#メソッドとしての処理
else
super
end
end
#誤り
def method_missing(name)
if @attributes.key? name
# メソッドとしての処理
end
# 例外が発生しないため、わからないよー><
end
また、method_missingで追加したメソッドについては、下記の様にどのレベルまでrespond_to?に対応するかは都度チームで決定し拡張しましょう。 ruby def respond_to?(name) @attributes.key?(method) || super end
- 必要のあるreturnは書く。(redirect_toとか)
- 必要のないreturnは省略しても良い。
#普通のruby
#推奨)
class Gay
def say
"I was gay"
end
end
#非推奨)
class Gay
def say
return "I was gay"
end
end
#Railsのcontrollerの場合...
#推奨)
class HogesController < ApplicationController
def index
redirect_to piyos_path and return
end
end
class HogesController < ApplicationController
def index
redirect_to piyos_path
return
end
end
#非推奨)
class HogesController < ApplicationController
def index
redirect_to piyos_path
end
end
redirect_to の後の return は基本的に書かなくても大丈夫だが、2重に return される時があるので、書いたほうが良い。
- インスタンス変数には@をつける。
- インスタンスメソッドにはself.をつける。
- local変数とInstance methodと同じ名前はつけない
# 例)
class Hoge
attr_accessor :title
def hoge
#ローカル変数
title = 'hoge'
puts title #=> hoge
#インスタンス変数(attr_accessor)
self.title = 'moge'
puts self.title #=> moge
puts title #=> hoge
#インスタンス変数(attr_accessor)
@title = 'foo'
puts @title #=> foo
puts self.title #=> foo
#メソッドの場合
pp = 'pp'
pp #変数ppが評価される
self.pp #=> oo メソッドppが評価される
end
def pp
puts 'oo'
end
end
- to_proc相当の機能は、Ruby 1.9 ではSymbolクラスへと統合されました。
#正解) どちらも読みやすい
words.map &:upcase
words.map(&:upcase)
#誤り)わかりずらい(と、いうかエラー)
words.map &:upcase + words.map &:capitalize
#従来)
words.map{|w| w.upcase} + words.map{|w| w.capitalize}
# 例)だんぜん読みやすくなりました!)
words.map(&:upcase) + words.map(&:capitalize)
#従来
sum = points.inject(0) {|sum, i| sum+i}
#to_sym
sum = points.inject(0, &:+)
- procよりもlambdaを積極的に使う
- lambdaリテラルを使う
- 下記の点で、できればlambdaを使う様にしましょう!
1)引数に厳格(ArgmentErrorを投げる) 2)returnがメソッドと同じ感覚で使える(LocalJumpErrorを投げない)
#引数の扱いの違い
a = lambda do |x,y|
end
b = proc do |x,y|
end
a.call #アウト(メソッド定義に近い)
b.call #セーフ(よろしくやってくれる)
#returnの違い
def hoge
p = proc { return }
p.call
p 'hoge' #LocalJumpError procのリターンはhogeメソッドから出てしまうため、この行は実行されない。
end
def hoge
p = lambda { return }
p.call
p. 'hoge' #lambdaのリターンはブロックからのリターンのため、この行は実行される。
end
#1.9以降のラムダリテラル
a = ->(x,y) do
end
#x,y=引数 i,n=ローカル変数定義
a = ->(x,y; i=0) do
end
#1.9以降procの呼び出し方法
f.call(x,y) #今まで通り
f[x,y]
f.(x,y)
- rescueを使う時は、何をキャッチしているのかを明確にするため、例外オブジェクトを明記する。
#正解
def moge
raise HogeError
rescue HogeError
puts $!
end
#もっと正解)基本的にはこちらを使用しましょう。
def foo
raise HogeError
rescue HogeError => ex
puts ex
end
#誤り
def hoge
raise HogeError
rescue
puts $!
end
- options={}パラメータのデフォルト値セット方法は以下を推奨します。
@default_config = {x:1, y:2}
def hoge(options={})
my_config = @default_config.merge options
end
- Fileのパスを作る場合は以下を推奨します。
#悪い例
path = "#{Rails.root}/tmp/hoge"
#良い例
path = File.join Rails.root, "tmp", "hoge"
- OSネイティブはなるべく呼ばないようにすることを推奨
DIR_PATH="/tmp/hoge"
#これはだめ
def init_dir
`mkdir -p #{DIR_PATH}`
end
#推奨
require 'fileutils'
def init_dir
FileUtils.mkdir_p DIR_PATH unless Dir.exist?(DIR_PATH) #無い場合のみ実行
end
- 代入側は呼び出したクラスのdowncaseにすることを推奨
#悪い例
obj = User.newu = User.new
#いい例
user = User.new
- development, product 環境ともに project_name で統一しましょう。
- test環境、またその他の環境に関しては project_name_environment で統一しましょう。
- DATE型はカラム名を*_onとする。
- DATETIME型はカラム名を*_atとする。
- 作成日、更新日はcreated_at、updated_atとする。
- マイグレーションでt.timestampは利用しないこと。
create_table :users do |t|
t.timestamp :moged_at # <= これはナシ
t.timestamp :ahoge_on # <= これはナシ
t.datetime :published_at
t.date :operated_on
t.timestamps # created_at, updated_at
end
- プロダクトコードに書く前に、テストコードを書きましょう。
- テストツールにはRSpecをつかいましょう。
- テストは自動化しましょう。
- プログラミング言語Ruby[ISBN978-4-87311-394-4]
- 達人プログラマー[ISBN4-89471-274-1]
- プログラミング作法[ISBN4-7561-3649-4]
- Kenji Hiranabe, コーディング標準(オリジナル) -- http://objectclub.esm.co.jp/eXtremeProgramming/CodingStd.doc
- Ruby コーディング規約 -- http://shugo.net/ruby-codeconv/codeconv.html