over 10 years ago

最近幾次上課同學都有問到 !? 的問題。因為已經回答三次了,覺得應該足夠做懶人包。

Ruby 中的 ! 與 ?

加在 method 後面,如 empty? 或 gsub!

在 Ruby 中,method 的命名,是允許後面加一個 !? 結尾。

一般的慣例是,如果

  • 設計一個 method 後面有 ?,如 empty?,表示回傳值「預期」會是 (boolean) true / false
  • 如果一個 method 後面有 !,如 gsub!,表示此 method 執行,「預期」會改變原物件裡面的值。

(如果你自己設計的 method,加 ? 其實不會自動轉 true / false,這只是一個「大家認為」「預期」應該的慣例)

2.0.0-p195 :001 > string = "ABC"
 => "ABC"
2.0.0-p195 :002 > string.gsub("A","a")
 => "aBC"
2.0.0-p195 :003 > string
 => "ABC"
2.0.0-p195 :004 > string.gsub!("A","a")
 => "aBC"
2.0.0-p195 :005 > string
 => "aBC"

加在變數前面,如 !current_user

! 前面表示相反值。

if !current_user:若 current_user 不存在

! 與 = 放在一起,如 !=

!= :就是 不等於

( current_user ) ? current_user.name : "Anonymous"

三元判斷式:上面這一段等於

if current_user
   current_user.name
else
  "Anonymous"
end

!!

!! 把該物件轉成 truefalse

2.0.0-p195 :008 > a = "a string"
 => "a string"
2.0.0-p195 :009 > !!a
 => true
2.0.0-p195 :010 > b = nil
 => nil
2.0.0-p195 :011 > !!b
 => false

Rails 中的 ! 與 ?

save 與 save! / create 與 create!

Rails 中的這兩組 save 與 create 與行為與 Ruby 的不太一樣。

其中 save / create,遇到過 validation 時,只會回傳 truefalse。但有時候我們要 debug 一個表單,有時候一直不知道為何表單為何沒成功一直 false,有時候會使用 save!create! 去 debug。這兩個 method 會 throw ActiveRecord::RecordInvalid exception 中斷程式。明確的告訴你壞在哪邊。

Rails 4.0 以前的 method?

在 Rails 4.0 以前的版本。若你有一個 boolean attribute 叫 is_admin。你可以直接在程式碼裡面呼叫 is_admin? (不需另外包裝)就會回傳 true / false

Rails 4.1 + 這個版本的 ! 與 ?

Rails 4.1+ 內建了方便實作類 state machine 的 enum 。!? 會自動幫你變更狀態和查詢狀態。

class Conversation < ActiveRecord::Base
  enum status: [ :active, :archived ]
end

# conversation.update! status: 0

conversation.active!
conversation.active? # => true

conversation.status  # => "active"


# conversation.update! status: 1

conversation.archived!
conversation.archived? # => true

conversation.status    # => "archived"


# conversation.update! status: 1

conversation.status = "archived"

# conversation.update! status: nil

conversation.status = nil
conversation.status.nil? # => true

conversation.status      # => nil


可以看到一些微妙的差別。

← 亞洲首次的 Ruby on Rails 年會 - Rails Pacific 9/26-9/27 Rails Pacific 2014 籌辦祕辛與心得 →
 
comments powered by Disqus