冒險村10 - or equals

10 - or equals

Ruby 的 ||=(or equals)運算符號使用頻率是個使用頻率滿高又方便的方法。在舉例實際會用到的情況之前,我們直接先講最後實際的意定義:如果變數已經被定義,則不會改變變數,如果沒有被定義,那就會賦值給變數。

所以是什麼意思呢?舉例來說:

1
2
3
4
my_name ||= "chester"
# => "chester"
my_name ||= "chester_2"
# => "chester"

由此可見驗證了上述的定義。但是,如果將變數等於 falsey 的值的情況時,則變數的值將會被更新

1
2
3
my_name = nil
my_name ||= "chester_falsey"
# => "chester_falsey"

同樣的在 hash 裡面也可以利用相同的原理來理解

1
2
3
4
5
6
7
8
9
10
hash = {}
# => {}
hash[:my_name] ||= "chester"
# => "chester"
hash
# => {:my_name=>"chester"}
hash[:my_name] ||= "chester_2"
# => "chester"
hash
# => {:my_name=>"chester"}

什麼時候使用呢?

舉個簡單的例子來看,如果想要撈其中一種性別類型的 User 資訊時,在 each 迴圈內 call 到 users 時就會去到下方的 def 來撈資料,並且只會撈一次存起來,在接下來的迴圈中也不會重複的去撈,更能提升速度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# @users = UserPresenter.new("male")
# @users.each ...(in view)

class UserPresenter
include Enumerable

def initialize(gender)
@gender = gender
end

def each(&_block)
users.each do |user|
yield format(user)
end
end

def format(user)
{
name: user.name,
email: user.email,
backup_email: user.backup_email,
company_name: user.company_name,
phone_number: user.phone_number,
# ...
}
end

def users
@_users ||= User.where(gender: gender)
end
end

不過小心如果撈的值每次都會不相同就不同使用這種方法來處理,不然跑第一次迴圈 變數已經被定義,後面不管是什麼都 不會改變變數