Join the social network of Tech Nerds, increase skill rank, get work, manage projects...
 
  • Overriding Equality of objects

    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 524
    Comment on it

    Overriding Equality of objects


    In ruby the equality of the objects depend upon several things, which are

    a) ==
    b) hash
    c) eql?

    In normal cases whenever you run == method for string numbers etc it works perfectly fine, but if there are two identical objects of a class it will always return false.

    Lets see an example:

    class Car
      attr_accessor :name
      def initialize(name)
        @name = name
      end
    end
    
    
    p Car.new("swift") == Car.new("swift")
    => false

    Thus we can see it gives the result false, even though both objects are identical. This is so because the hash of the objects are different and if every time you initialize an object it will return different hash value like this:

    > Car.new("swift")
     => #<Car:0x000000022d85c8 @name="swift">
    > Car.new("swift")
     => #<Car:0x000000022b4808 @name="swift">


    Thus you can see the difference here, now suppose if you have a use case like this that if the attributes of the objects are identical then you need to show them as equal. To do that you need to override the == method in your class like this:

    class Car
      attr_accessor :name
      def initialize(name)
        @name = name
      end
    
      def ==(other_obj)
        if self.name == other_obj.name
          return true
        else
          return false
        end
      end
    end
    
     p Car.new("swift") == Car.new("swift")
     => true
    
     p Car.new("swift") == Car.new("fiat")
     => false

    Here we have solve the problem of one operator but suppose we have an array of multiple objects and you want to perform uniq on them, then in that case it doesn't only depends upon the == operator. it is also dependent upon the eql? method and hash method. so we also need to override them too.

    ## before overriding
    
    > [Car.new("swift"), Car.new("swift"), Car.new("swift")]
    => [#<Car:0x000000021c2288 @name="swift">, #<Car:0x000000021c2238
    @name="swift">, #<Car:0x000000021c21e8 @name="swift">]

     

    Now we will override eql? method and hash method

    class Car
      attr_accessor :name
      def initialize(name)
        @name = name
      end
    
      ## Overriding == method
      def ==(other_obj)
        if self.name == other_obj.name
          return true
        else
          return false
        end
      end
    
      ##  Overriding eql method
      def eql?(other_obj)
            if self.name == other_obj.name
          return true
        else
          return false
        end
      end
    
      ## Overriding hash method
      ## Here we will just use the hash for the name attribute
      def hash
        self.name.hash
      end
    end

     

     Now if you run the uniq on identical object array you will get only one element

    > [Car.new("swift"), Car.new("swift"), Car.new("swift")].uniq
    [#<Car:0x00000002059f18 @name="swift">]

     

 0 Comment(s)

Sign In
                           OR                           
                           OR                           
Register

Sign up using

                           OR                           
Forgot Password
Fill out the form below and instructions to reset your password will be emailed to you:
Reset Password
Fill out the form below and reset your password: