4

I have a custom defined class Instruction. Instances are initialized and collected in an array. There are some duplicate (all instance variables identical) instances and I want to filter them out.

class Instruction
    attr_accessor :date, :group, :time
    def initialize(date, group, time)
        @date, @group, @time = date, group, time
    end
end

instructions = Array.new

instructions.push ( Instruction.new('2000-01-01', 'Big', '10am') )
instructions.push ( Instruction.new('2000-01-01', 'Small', '9am') )
instructions.push ( Instruction.new('1999-09-09', 'Small', '4pm') )
instructions.push ( Instruction.new('2000-01-01', 'Small', '9am') )

instructions.uniq.each {|e| puts "date: #{e.date} \tgroup: #{e.group} \ttime: #{e.time}"}

I would expect one of the '2000-01-01', 'Small', '9am' entries removed by .uniq, however I still see the repeated entry in the output.

I have tried adding == and eql? methods to the class definition as follows:

def ==(other)
    other.class == self.class && other.date == self.date && other.group == self.group && other.time == self.time
end
alias :eql? :==

But that didn't work either... Help!

2 Answers 2

4

Your use of uniq did not work because, even when the two of the instances of Instruction may share the values of @date, @group, @time, their identity are different. You have to compare the values of these instance variables, not the instance of Instruction itself.

instructions.uniq{|e| [e.date, e.group, e.time]}
Sign up to request clarification or add additional context in comments.

Comments

3

You forgot to override hash. eql? only gets called for objects with the same hash value.

3 Comments

why single eql? or hash is not enough? I do not understand
eql? only gets called for objects with the same hash value, but then it is required. So, only overriding one of them simply does not properly implement the protocol.
I just wanted to know why simply hash is nit enough to compare? Or eql?, which alone is 100% guarantor of equality? Why do we need them both?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.