So sánh trong Ruby
Bài đăng này đã không được cập nhật trong 7 năm
I. Giới thiệu
Làm thế nào để ta so sánh giữa 2 đối tượng trong Ruby? Chắc hẳn bạn đã biết phép so sánh ==
giống như các ngôn ngữ lập trình khác...nhưng bạn có biết ==
là một phương thức và nó không chỉ là cú pháp thông thường.
Bạn có thể xây dựng phương thức này ở trong class của bạn để làm cho nó mạnh mẽ hơn. Và bài này tôi sẽ nói về vấn đề đó.
II. Phép so sánh căn bản
Như bạn biết muốn so sánh 2 string ta làm như sau:
"foo" == "foo"
Và nếu như nội dung của 2 chuỗi so sánh giống nhau thì phép so sánh trả về true. Phép so sánh ở đây nó hoạt động được với string bởi vì lớp string
đã cài đặt phương thức ==
, nó hiểu như là để so sánh giữa 2 đối tượng string.
Nhưng nếu lớp String
không cài đặt phương thức ==
thì sao?
Ruby nên sử dụng phép so sánh ==
để cài đặt cho đối tượng. Ví dụ:
Object.new == Object.new # false
String.new == String.new # true
III. Cài đặt phép so sánh
Bây giờ hãy học cách làm cho class của bạn mạnh mẽ hơn và có thể so sánh giữa 2 thể hiện của class đó.
Nhờ phương thức ==
bạn có thể định nghĩa chính xác điều gì khi ta so sánh giữa 2 thể hiện của lớp đó.
Ví dụ:
class Product
attr_reader :name, :price
def initialize(name, price)
@name, @price = name, price
end
def ==(other)
self.name == other.name &&
self.price == other.price
end
end
p1 = Product.new('book', 49)
p2 = Product.new('book', 49)
p1 == p2 # true
Phương thức ==
ở trên có nghĩa là khi mà 2 sản phẩm cùng name
và price
giống nhau, phương thức ==
sẽ trả về true và ngược lại.
Chú ý: Nếu bạn không cài đặt phương thức này, mặc định khi ta so sánh giữa 2 thể hiện của 1 lớp, và đã tồn tại trong database, nó sẽ so sánh cả id
của 2 thể hiện đó.
Và Struct
cũng được cài đặt phương thức ==
cho chúng ta.
IV. Phép so sánh ===
Bạn có thể tự hỏi mình ==
là phương thức, liệu ===
nó có phải là một phương thức ? Câu trả lời ở đây là có !
Và sư khác biệt giữa chúng là gì ?
Trong javascript, chúng ta có sự khác biệt giữa 2 phương thức này, ==
sẽ chuyển đổi kiểu cho 2 đối tượng chúng ta so sánh về kiểu giống nhau để so sánh, ví dụ như "1" == 1
sẽ trả về true, còn ===
sẽ so sánh cả về mặt kiểu dữ liệu của 2 đối tượng đó, ví dụ "1" === 1
sẽ trả về false.
Nhưng ở trong ruby, nó không phải là như vậy. Mà ===
còn phụ thuộc vào lớp mà bạn cài đặt.
Trong nhiều trường hợp, nó chỉ là phép thông thường như ==
, như ta thực hiện với string
và Object
.
Dưới đây là bảng chỉ ta ý nghĩa đặc biệt của phương thức ===
phụ thuộc vào hoàn cảnh của chúng ta sử dụng.
Lớp | Ý nghĩa |
---|---|
Range | Trả về true nếu đối tượng là 1 thành phần của range, false trong trường hợp khác |
Regexp | So sánh 2 regexp như là chuỗi |
Module | Trả về true nếu đối tượng là thể hiện của module và thể hiện của module con |
V. Tổng kết.
Trong bài này tôi chỉ cho bạn cách đơn giản để cho class
của bạn mạnh mẽ hơn nhờ thực hiện xây dựng phép so sánh ở trong class
đó, và sự khác nhau, giống nhau giữa 2 phép so sánh ===
và ==
All rights reserved