Pemula akan mengalami masalah dengan metode kesetaraan :
- a == b : memeriksa apakah a dan b sama. Ini yang paling berguna.
- a.eql? b : juga memeriksa apakah a dan b sama, tetapi terkadang lebih ketat (mungkin memeriksa bahwa a dan b memiliki tipe yang sama, misalnya). Ini terutama digunakan di Hashes.
- a.equal? b : memeriksa apakah a dan b adalah objek yang sama (pemeriksaan identitas).
- a === b : digunakan dalam pernyataan kasus (saya membacanya sebagai " a pertandingan b ").
Contoh berikut seharusnya menjelaskan 3 metode pertama:
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
Perhatikan bahwa == , eql? dan setara? harus selalu simetris: jika a == b maka b == a.
Perhatikan juga bahwa == dan eql? keduanya diimplementasikan di kelas Object sebagai alias sama? , jadi jika Anda membuat kelas baru dan ingin == dan eql? untuk mengartikan sesuatu selain identitas biasa, maka Anda harus mengesampingkan keduanya. Sebagai contoh:
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
The === Metode berperilaku berbeda. Pertama-tama ini tidak simetris (a === b tidak berarti bahwa b === a). Seperti yang saya katakan, Anda bisa membaca a === b sebagai "a korek api b". Berikut beberapa contoh:
# === 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)
The kasus Pernyataan ini didasarkan pada === metode:
case a
when "joe": puts "1"
when 1.0 : puts "2"
when (1..10), (15..20): puts "3"
else puts "4"
end
setara dengan ini:
if "joe" === a
puts "1"
elsif 1.0 === a
puts "2"
elsif (1..10) === a || (15..20) === a
puts "3"
else
puts "4"
end
Jika Anda mendefinisikan kelas baru yang instansinya mewakili semacam wadah atau rentang (jika memiliki sesuatu seperti metode include? Atau cocok? ), Anda mungkin merasa berguna untuk mengganti metode === seperti ini:
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