Người mới sẽ gặp khó khăn với các phương pháp bình đẳng :
- a == b : kiểm tra xem a và b có bằng nhau không. Điều này là hữu ích nhất.
- a.eql? b : cũng kiểm tra xem a và b có bằng nhau hay không, nhưng đôi khi nó nghiêm ngặt hơn (nó có thể kiểm tra xem a và b có cùng kiểu không). Nó chủ yếu được sử dụng trong Hashes.
- a. hệ quả? b : kiểm tra xem a và b có phải là cùng một đối tượng hay không (kiểm tra danh tính).
- a === b : được sử dụng trong câu lệnh trường hợp (tôi đọc nó là " a khớp với b ").
Những ví dụ này sẽ làm rõ 3 phương pháp đầu tiên:
a = b = "joe"
a==b # true
a.eql? b # true
a.equal? b # true (a.object_id == b.object_id)
a = "joe"
b = "joe"
a==b # true
a.eql? b # true
a.equal? b # false (a.object_id != b.object_id)
a = 1
b = 1.0
a==b # true
a.eql? b # false (a.class != b.class)
a.equal? b # false
Lưu ý rằng == , eql? và bằng nhau? nên luôn luôn đối xứng: nếu a == b thì b == a.
Cũng lưu ý rằng == và eql? cả hai đều được thực hiện trong lớp Object dưới dạng bí danh để bằng nhau? , vì vậy nếu bạn tạo một lớp mới và muốn == và eql? nghĩa là một cái gì đó khác ngoài danh tính rõ ràng, thì bạn cần ghi đè cả hai. Ví dụ:
class Person
attr_reader name
def == (rhs)
rhs.name == self.name # compare person by their name
end
def eql? (rhs)
self == rhs
end
# never override the equal? method!
end
Các === phương pháp xử lý khác nhau. Trước hết nó không đối xứng (a === b không ngụ ý rằng b === a). Như tôi đã nói, bạn có thể đọc a === b là "a khớp với b". Đây là vài ví dụ:
# === is usually simply an alias for ==
"joe" === "joe" # true
"joe" === "bob" # false
# but ranges match any value they include
(1..10) === 5 # true
(1..10) === 19 # false
(1..10) === (1..10) # false (the range does not include itself)
# arrays just match equal arrays, but they do not match included values!
[1,2,3] === [1,2,3] # true
[1,2,3] === 2 # false
# classes match their instances and instances of derived classes
String === "joe" # true
String === 1.5 # false (1.5 is not a String)
String === String # false (the String class is not itself a String)
Câu lệnh trường hợp dựa trên phương thức === :
case a
when "joe": puts "1"
when 1.0 : puts "2"
when (1..10), (15..20): puts "3"
else puts "4"
end
tương đương với điều này:
if "joe" === a
puts "1"
elsif 1.0 === a
puts "2"
elsif (1..10) === a || (15..20) === a
puts "3"
else
puts "4"
end
Nếu bạn xác định một lớp mới có các cá thể đại diện cho một số loại vùng chứa hoặc phạm vi (nếu nó có một cái gì đó như phương thức include? Hoặc match? ), Thì bạn có thể thấy hữu ích khi ghi đè phương thức === như thế này:
class Subnet
[...]
def include? (ip_address_or_subnet)
[...]
end
def === (rhs)
self.include? rhs
end
end
case destination_ip
when white_listed_subnet: puts "the ip belongs to the white-listed subnet"
when black_listed_subnet: puts "the ip belongs to the black-listed subnet"
[...]
end