Toán tử "===" - ma thuật trong so sánh bằng.



  • 1. Triple equals là gì?

    Triple Equals - được mọi người biết đến một trong hai toán tử so sánh bằng trong Ruby với công dụng so sánh ngang bằng về giá trị và kiểu dữ liệu. === được sử dụng để xác định sự bình đẳng trong các trường hợp được khai báo.
    Trong trường hợp mặc định, triple equals (===) chỉ là một bí danh cho double equals (==). Nó được thể hiện rõ ràng nhất khi các lớp ghi đè lên hành vi của chính mình. Hãy cùng xem xét một số ví dụ về điều này nhé:

    Ranges

    rng === anObject -> true or false
    Ex: (1..10) === 1
    

    Với range, triple equal là bí danh cho include?. Kết quả toán tử sẽ trả về True nếu anObject là một phần tử thuộc rng, sẽ trả về False trong trường hợp ngược lại. Thuận tiện, === là toán tử so sánh được sử dụng bởi câu lệnh case when :

    case 79
     when 1..50   then   print "low\n"
     when 51..75  then   print "medium\n"
     when 76..100 then   print "high\n"
    end
        
    Output: high
    

    Regex

    rxp === aString -> true or false
    Ex: /abc/ === 'abcdef'
    

    Với regex, === chính là bí danh cho match. Nếu aString thỏa mãn, là một thể hiện của đoạn mã rxp thì kết quả nhận được là true, trường hợp còn lại kết quả sẽ là false. Trong syntax của câu lệnh case when :

    
    a = "HELLO"
    case a
    when /^a-z*$/; print "Lower case\n"
    when /^A-Z*$/; print "Upper case\n"
    else;            print "Mixed case\n"
    end
    
    output: Upper case
    

    Classes

       String === 'foo'
    

    Với class, === là bí danh cho i_sa?. Kết quả là true nếu đối tượng thuộc class, ngược lại sẽ nhận được kết quả là false.

    Procs

    -> a { a > 5 } === 6
    

    Với proc, === tương tự với phương thức call.

    IPAddr

       IPAddr.new('10.0.0.0/8') === '10.0.0.1'
    

    Cái bạn nhìn thấy hoàn toàn đúng. IPAddr ghi đè bằng === bao gồm cả subnet và hậm chí là đủ để ép buộc bất cứ điều gì bạn đưa nó vào IPAddr để so sánh. Người quản trị hệ thống sẽ đặc biệt quan tâm đến việc này. Việc sử dụng trong case when cũng gần giống với việc sử dụng toán tử === trong các mảng trên:

    case '10.0.0.1'
    when IPAddr.new('10.0.0.0/8') then 'wired connection'
    when IPAddr.new('192.168.1.0/8') then 'wireless connection'
    else 'unknown connection'
    end
    output: "wired connection"
    

    2. Querying

    Hầu hết các bạn đã từng thấy ActiveRecord trước đó, giống như cách mà tôi truy vấn đối với mô hình Person:

       Person.where(name: 'Bob', age: 10..20)
    

    Bạn biết điều gì sẽ tốt nếu chúng ta có thể làm điều gì đó tương tự như với các mảng cũ. Hãy nhớ rằng triple equals đã làm được những gì với ranges and regex và với tất cả những cái khác nữa. Hãy đi tìm hiểu một số điều thú vị với nó nhé.
    Hãy bắt đầu với một mảng các hashes nhé:

    people = [
      {name: 'Bob', age: 20},
      {name: 'Sue', age: 30},
      {name: 'Jack', age: 10},
      {name: 'Jill', age: 4},
      {name: 'Jane', age: 5}
    ]
    

    Tôi muốn lấy ra tất cả các người trong mảng trên có tuổi lớn hơn 20. Như cách thông thường trong Ruby bạn sẽ làm như sau:

    people.select { |person| person[:age] >= 20 }
    

    Nếu thêm một vài điều kiện thì nó sẽ bắt đầu nhận được một rắc rồi. Điều này sẽ khá khó chịu nếu chúng ta đang đi qua rất nhiều JSON, vậy tại sao không sử dụng từ ActiveRecord?

    def where(list, conditions = {})
      return list if conditions.empty?
      list.select { |item|
        conditions.all? { |key, matcher| matcher === item[key] }
      }
    end
    

    Hãy nhìn cách mà === hoạt động. Điều đó có nghĩa là chúng ta không thể làm chính xác được sự bằng nhau, nhưng chúng ta sẽ nhận được các giá trị đơn matches được ở trên là tốt.

    3. JSON Packet Dump

    Chúng ta có thể truy vấn với một số loại gói tin dump trong JSON:

    where(packets,
      source_ip: IPAddr.new('10.0.0.0/8'),
      dest_ip:   IPAddr.new('192.168.0.0/16')
      ttl:       -> v { v > 30 }
    )
    

    Không đủ sức mạnh? Hãy nhớ rằng chúng ta cũng có quyền truy cập vào Proc, có nghĩa là bạn hoàn toàn có thể sử dụng thành phần để có được một số truy vấn phức tạp thú vị bằng cách sử dụng một cái gì đó như Ramda trong Ruby:

    where(packets,
      source_ip: IPAddr.new('10.0.0.0/8'),
      dest_ip:   IPAddr.new('192.168.0.0/16')
      ttl:       R.gt(30)
    )
    

    Đủ để thấy, Ruby cho chúng ta === trên Proc cho phép một số ma thuật thực hiện với framework giống như Ramda.

    Có rất nhiều thứ bạn có thể làm với triple equals, kết hợp với từng chức năng bạn có thể phát hiện ra rất nhiều điều thú vị từ nó, trên đây mình chỉ giới thiệu qua với các bạn phần nhỏ nói về những hữu ích mà nó mang lại. Mong rằng nó sẽ đem lại cho các bạn một cái nhìn mới về toán tử so sánh bằng này.
    Nguồn: Viblo


Hãy đăng nhập để trả lời
 

Có vẻ như bạn đã mất kết nối tới LaptrinhX, vui lòng đợi một lúc để chúng tôi thử kết nối lại.