[Ruby] 「===」和「==」一樣嗎?

披著等號外皮的多功能運算子

三等號===)」和「雙等號(==)」是許多Ruby初學者經常搞混的兩個運算子。一些類別會根據自己的需要而覆寫三等號。本篇會介紹三等號===的用法。

物件相等性

三等號只有在Object#===時與Object#==相等。

1
2
3
4
s1 = "apple"
s2 = "apple"
s1 == s2 # => true
s1 === s2 # => true

型態匹配

Module類別覆寫了三等號,使其可以確認物件的型態。例如:

1
2
3
4
5
6
7
8
3.is_a? Integer # => true
Integer === 3 # => true

"apple".is_a? Integer # => false
Integer === "apple" # => false

Module === Object # => true
Object === Module # => true

範圍匹配

Range類別亦覆寫了三等號,使其可以確認物件是否在範圍內。例如:

1
2
3
4
5
(0...3).include? 0 # => true
(0...3) === 0 # => true

("a"..."z").include? "z" # => false
("a"..."z") === "z" # => false

字串匹配

Regexp類別也覆寫了三等號,使其可以確認字串是否符合正規表示式(Regular Expression)。例如:

1
2
/a+/ =~ "apple" # => 0
/a+/ === "apple" # => true

Proc#call

若左手邊是Proc類別的物件,則其功能等同於Proc#call。例如:

1
2
3
cube = Proc.new { |x| x ** 3 }
cube.call 3 # => 27
cube === 3 # => 27

Case Equality Operator

三等號有一個名稱叫「Case Equality Operator」。在case...when...else中,when便會呼叫===來匹配,使程式碼更簡潔。

1
2
3
4
5
6
7
8
case score
when 0...60
  "failed"
when 60..100
  "passed"
else
  "wrong score"
end

整理

以下整理各類三等號的等同方法。

方法
Object#==, #eql?
Module#is_a?, #kind_of?
Range#include?, #member?
Regexp(#=~)(不完全相同)
Proc#call, #yield, #[]

參考資料

updatedupdated2020-07-242020-07-24