使用 def 時,當有參數時使用括號。當方法不接受任何參數時,省略括號。
def some_method
# 省略主體
end
def some_method_with_arguments(arg1, arg2)
# 省略主體
end
永遠不要使用 for ,除非你很清楚為什麼。大部分情況應該使用迭代器來取代。for 是由 each 所實作的(所以你加入了一層的迂迴),但出乎意料的是 — for 並沒有包含一個新的視野 (不像是 each)而在這個區塊中定義的變數將會被外部所看到。
arr = [1, 2, 3]
# 不好
for elem in arr do
puts elem
end
# 好
arr.each { |elem| puts elem }
永遠不要在多行的 if/unless 使用 then
# 不好
if some_condition then
# 省略主體
end
# 好
if some_condition
# 省略主體
end
偏愛三元運算元 ? : 勝於 if/then/else/end 結構。它更為常見及更精準。
# 不好
result = if some_condition then something else something_else end
# 好
result = some_condition ? something : something_else
使用一個表達式給一個三元運算元的分支。這也意味著三元運算符不要寫成巢狀式。巢狀情況使用 if/else 結構。
# 不好
some_condition ? (nested_condition ? nested_something : nested_something_else) : something_else
# 好
if some_condition
nested_condition ? nested_something : nested_something_else
else
something_else
end
永遠不要使用 if x: ... — 它已經在 Ruby 1.9 被移除了。使用三元運算元來取代。
# 不好
result = if some_condition: something else something_else end
# 好
result = some_condition ? something : something_else
永遠不要使用 if x; ... 使用三元運算元來取代。
一行的情況使用 when x then ... 。替代方案的語法 when x: ... 在 Ruby 1.9 被移除了。
永遠不要使用 when x; ... 。參考前一個規則。
布林表達式使用 &&/||,控制流程使用 and/or。
(經驗法則:如果你需要使用外部括號,你正在使用錯誤的運算元。)
# 布林表達式
if some_condition && some_other_condition
do_something
end
# 控制流程
document.saved? or document.save!
避免多行的 ? :(三元運算元),使用 if/unless 來取代。
當你有單行的主體時,偏愛 if/unless 修飾符。
另一個好的方法是使用控制流程的 and/or 。
# 不好
if some_condition
do_something
end
# 好
do_something if some_condition
# 另一個好方法
some_condition and do_something
否定條件偏愛 unless 優於 if (或是控制流程 or)。
# 不好
do_something if !some_condition
# 好
do_something unless some_condition
# 另一個好方法
some_condition or do_something
永遠不要使用 unless 搭配 else。 將它們改寫成肯定條件。
# 不好
unless success?
puts 'failure'
else
puts 'success'
end
# 好
if success?
puts 'success'
else
puts 'failure'
end
不要使用括號圍繞 if/unless/while 的條件式,除非這條件包含了一個賦值(見下面使用 = (一個賦值)的回傳值)。
# 不好
if (x > 10)
# 省略主體
end
# 好
if x > 10
# 省略主體
end
# 好
if (x = self.next_value)
# 省略主體
end
忽略圍繞方法參數的括號,如內部 DSL (如:Rake, Rails, RSpec),Ruby 中帶有“關鍵字”狀態的方法(如:attr_reader, puts)以及屬性存取方法。
所有其他的方法呼叫,使用括號圍繞參數。
class Person
attr_reader :name, :age
# 忽略
end
temperance = Person.new('Temperance', 30)
temperance.name
puts temperance.age
x = Math.sin(y)
array.delete(e)
單行區塊喜好 {...} 勝於 do..end。多行區塊避免使用 {...}(多行串連總是醜陋)。在 do...end 、“控制流程”及“方法定義”,永遠使用 do...end (如 Rakefile 及某些 DSL)。串連時避免使用 do...end。
names = ["Bozhidar", "Steve", "Sarah"]
# 好
names.each { |name| puts name }
# 不好
names.each do |name|
puts name
end
# 好
names.select { |name| name.start_with?("S") }.map { |name| name.upcase }
# 不好
names.select do |name|
name.start_with?("S")
end.map { |name| name.upcase }
某些人會爭論多行串連時,使用 {...} 看起來還可以,
但他們應該問問自己 — 這樣程式碼真的可讀嗎
以及不能把區塊內容取出來放到絕妙的方法中嗎。
避免在不需要的場合時使用 return 。
# 不好
def some_method(some_arr)
return some_arr.size
end
# 好
def some_method(some_arr)
some_arr.size
end
當賦予預設值給方法參數時,使用空格圍繞 = 運算元。
# 不好
def some_method(arg1=:default, arg2=nil, arg3=[])
# 做些事情...
end
# 好
def some_method(arg1 = :default, arg2 = nil, arg3 = [])
# 做些事情...
end
然而幾本 Ruby 書建議第一個風格,
第二個風格在實踐中更為常見(並可爭議地可讀性更高一點)。
避免在不需要的場合使用續行 \ 。在實踐中,盡量避免使用續行。
# 不好
result = 1 - \
2
# 好 (但仍然醜的跟地獄一樣)
result = 1 \
- 2
使用 =(一個賦值)的回傳值是好的,但用括號環繞賦值。
# 好 — 演示賦值的目標用途
if (v = array.grep(/foo/)) ...
# 不好
if v = array.grep(/foo/) ...
# 也很好 — 演示賦值的目標用途及有正確的優先順序
if (v = self.next_value) == "hello" ...
隨意使用 ||= 來初始化變數
# 僅在name為nil或false時,把名字設為 Bozhidar。
name ||= 'Bozhidar'
不要使用 ||= 來初始化布林變數。
(想看看如果現在的值剛好是 false 時會發生什麼。)
# 不好 — 會把 enabled 設成真,即便它本來是假。
enabled ||= true
# 好
enabled = true if enabled.nil?
避免使用 Perl 風格的特別變數(像是 $0-9, $`, 等等)。它們看起來非常神祕以及不鼓勵使用一行的腳本。
避免在方法名與左括號之間放一個空格。
# 不好
f (3 + 2) + 1
# 好
f(3 + 2) + 1
如果方法的第一個參數由左括號開始,永遠在這個方法呼叫裡使用括號。
舉個例子: f((3+2) + 1)。
總是使用 -w 來執行 Ruby 直譯器,如果你忘了某個上述的規則,它就會警告你!
當你的雜湊鍵是符號時,使用 Ruby 1.9 雜湊字面語法。
# 不好
hash = { :one => 1, :two => 2 }
# 好
hash = { one: 1, two: 2 }
使用新的 lambda 字面語法。
# 不好
lambda = lambda { |a, b| a + b }
lambda.call(1, 2)
# 好
lambda = ->(a, b) { a + b }
lambda.(1, 2)
未使用的區塊參數使用 _ 。
# 不好
result = hash.map { |k, v| v + 1 }
# 好
result = hash.map { |_, v| v + 1 }