Ruby 如何避免 method chain 噴掉:Safe Navigation Operator (&.)

NickWarm
Nickwarm Journey
Published in
3 min readAug 9, 2018
Photo by Miranda Wipperfurth on Unsplash

在 Ruby 裡,我們常會寫method chain,i.e:

user.friends.first.email?

在上面的範例程式中,若其中一個沒有值,整個程式就會噴掉,i.e:

一個user沒朋友 ( user.friends.first # => nil ) ,則會噴

user.friends.first.email?
# => NoMethodError: undefined method `email' for nil:NilClass

然後程式就會噴掉

有時候,很重要的頁面,像是網站的首頁,不能讓它的method chain一個nil就整頁噴掉

假如 Ruby 版本 >= 2.3 ,就可以使用 safe navigation operator &. 來處理這種情況

以上面的user沒朋友做例子

user.friends.first&.email?
# => nil

如此一來就不會整個網頁都噴掉了

假如 Ruby 太舊,不能用 &. 該如何處理

早在 rails v3.0.0, rails 擴充的 Object 就有 try 可以用,上面的例子可以寫成:

user.friends.first.try(:email?)

而 try 其實就是做了這件事

@user && @user.name

當然,我們可以寫個簡單的小程式驗證一下

# hhh.rb
class A
def aaa
"aaa"
end
end
# 進 pry
$ pry
[1] pry(main)> load 'hhh.rb'
=> true
[2] pry(main)> a = A.new
=> #<A:0x007fd1f616c888>
[3] pry(main)> a.aaa
=> "aaa"
[4] pry(main)> a && a.aaa
=> "aaa"
[5] pry(main)> nil && nil.aaa
=> nil

題外話一下,Ruby 可以用 nil && nil.anything 這寫法真讓我驚奇

[25] pry(main)> nil && nil.seat
nil
[26] pry(main)> nil && nil.set
nil
[27] pry(main)> nil.set
NoMethodError: undefined method 'set'for nil:NilClass
from (pry):27:in '<main>'

ref: rails v5.2.0try 的實作

相關文章

--

--

NickWarm
Nickwarm Journey

Rubyist。Nicholas aka Nick. Experienced in Ruby, Rails. I like to share the experiences what I learned.