提升你代碼質量的10個Ruby小技巧
在 Ruby 中有很多你可能并不知道,但實際上非常實用的小技巧。下面筆者就結合自身經驗,向大家分享一些。
1.構造Hash
你可以用一個列表一系列的值構造 Hash 通過 Hash[...] 方法,它將會像下面的方式創建一個 Hash:
Hash['key1', 'value1', 'key2', 'value2'] # => {"key1" => "value1", "key2" => "value"}
2.Lambda字面量->
定義一個 lambda 可以使用在 Rails 中也用的比較流行的 -> 字面量,它可以很容易的定義一個 lambda 對象
a = -> {1 + 1} a.call # => 2 a = ->(arg) {arg + 1} # 含參 a.call(2) # 傳遞參數 # => 3
3.雙星 **
雙星在 Ruby 中是一個小魔法,來看看下面的方法:
def my_method(a, *b, **c) end
a是一個常規的參數,b將會得到第一個參數后面的所有參數并把他們放入一個數組中, **c將會得到傳人方法的任何格式為key: value的參數。
來看看下面的例子: 一個參數
my_method(1) # => [1, [], {}]
超過一個參數
my_method(1, 2, 3, 4) # => [1, [2, 3, 4], {}]
超過一個參數 + hash-style 參數
my_method(1, 2, 3, 4, a: 1, b: 2) # => [1, [2, 3, 4], {:a => 1, :b => 2}]
4.操作單個對象和數組用同樣的方式
有時你可能會先給出一個選項去接受單個對象或者一個數組對象,而不是最后去檢查你接受到對象的類型,這時你可以用 [*type]或者 Array(type)
我們先設置兩個變量,第一個是單對象,第二個是數字數組:
obj = 1 obj_arr = [1, 2, 3]
在下面的例子,通過任何被給定的對象用 [*...] 去循環:
[*obj].each { |s| s } # => [1] [*obj_arr].each { |s| s } # => [1, 2, 3]
和上面效果一樣,這次用 Array(...):
Array(stuff).each { |s| s } # => [1] Array(stuff_arr).each { |s| s } # => [1, 2, 3]
5. ||= 操作符號
利用 ||= 操作符能寫出很簡潔的代碼
它實際上和下面的表示方式相同:
a || a = b # 正確
大多數人都認為它和下面的表示方式一樣,但實際不是:
a = a || b # 錯誤
因為如果 a 已經存在,第二種方法的表示就是再給 a 進行分配賦值,但這樣其實是沒有意義的。
6.強制的哈希參數
這個是在 Ruby 2.0 被引進的,你可以在定義方法時指定接受的參數為 hash 類型,像這樣:
def my_method({}) end
你可以指定想要接受值的鍵,或者為鍵指定一個默認的值。下面的 a 和 b 是指定要接受值的鍵:
def my_method(a:, b:, c: 'default') return a, b, c end
我們不給 b 傳值來調用它,這時會報錯:
my_method(a: 1) # => ArgumentError: missing keyword: b
由于 c 有一個默認的值,我們可以僅僅只給 a 和 b 傳值:
my_method(a: 1, b: 2) # => [1, 2, "default"]
或者是給所有鍵傳值:
my_method(a: 1, b: 2, c: 3) # => [1, 2, 3]
我們大多時候的做法是直接傳入一個 hash,這樣的做法只是看起來更明顯,就像下面的方式:
hash = { a: 1, b: 2, c: 3 } my_method(hash) # => [1, 2, 3]
7.生成字符或者字符數組
你可能想要生成一個數字列表或者把所有的字符放入一個數組,你可以用 Ruby 的 range 去做這樣的事。
A到Z:
('a'..'z').to_a # => ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]
1到10:
(1..10).to_a # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
8. Tap
tap 是一個很好的小方法去提高代碼的可讀性,我們拿下面的類作為例子:
class User attr_accessor :a, :b, :c end
現在去實例化一個對象并為對象的屬性去賦值,你可能會這么做:
def my_method o = User.new o.a = 1 o.b = 2 o.c = 3 o end
或者你可以用tap使用下面的方式去做:
def my_method User.new.tap do |o| o.a = 1 o.b = 2 o.c = 3 end end
基本上,tap 方法引入被調用的對象到代碼塊中并最后返回它。
9.Hash 默認的值
默認的,當我們試圖接受一個在 hash 中未定義的值,你將會得到 nil。但你可以改變這個結果在進行初始化時。 (提示:一般不要這樣做除非你知道自己在干什么)
在第一個例子中,我們定義了一個默認的值為0,所以當我們 a[:a] 時會得到 0 而不是 nil:
a = Hash.new(0) a[:a] # => 0
我們能夠傳入任何形式類型到 Hash 初始函數中:
a = Hash.new({}) a[:a] # => {}
或者是一個字符串:
a = Hash.new('lolcat') a[:a] # => "lolcat"
10. here 文檔
here 文檔有一個缺點就是它會影響代碼流暢和縮進問題,由于 HERE 會縮進兩格,但有時為了最后內容連續性,你可能會把每行內容都靠左寫,像這樣:
def my_method <<-HERE Ruby stricks Interesting Right HERE end
這有一個技巧可以避免它,通過用 gsub 方法加一個正則表達式。你可以自動的去除前面的空格,這樣你就能保持縮進。
def my_method <<-HERE.gsub(/^\s+/, '') Ruby stricks Interesting Right HERE end