Ruby sort - why rspec error when "expected: [7, 6, 5, 5, 4, 3, 3]" seems the same as "got: [7, 6, 5, 5, 4, 3, 3]"? [closed]

StackOverflow https://stackoverflow.com/questions/19228274

Question

Result:

Failures:

  1) An usual sorter sorts downwards by default
     Failure/Error: [a,b,c,d,e,f,g].sort.should == [7,6,5,5,4,3,3]
       expected: [7, 6, 5, 5, 4, 3, 3]
            got: [7, 6, 5, 5, 4, 3, 3] (using ==)
     # ./downsort_spec.rb:13:in `block (2 levels) in <top (required)>'

Finished in 0.00077 seconds

Test:

require_relative 'my_sorter.rb'

describe "A usual sorter" do
  it "sorts downwards by default" do
    my_array= [3,5,7,5,3,6,4,2,5,6]
    a=MySorter.new(3)
    b=MySorter.new(5)
    c=MySorter.new(7)
    d=MySorter.new(5)
    e=MySorter.new(3)
    f=MySorter.new(6)
    g=MySorter.new(4)
    [a,b,c,d,e,f,g].sort.should == [7,6,5,5,4,3,3]
  end 
end

Code:

class MySorter
  include Comparable
  attr_reader :value

  def initialize(value)
    @value = value
  end

  def <=> (other)
    if value > other.value then
      -1
    elsif value < other.value then
      1
    else
       0
    end
  end

  def inspect
    @value
  end

end

I have a very simple sort for now, the intent will be a more complex one once I have this working (hence the detail in the comparison method).

Was it helpful?

Solution

You are comparing an array of MySorter objects to an array of Fixnums. You need to change this:

[a,b,c,d,e,f,g].sort.should == [7,6,5,5,4,3,3]

to

[a,b,c,d,e,f,g].sort.map(&:value).should == [7,6,5,5,4,3,3]

OTHER TIPS

An alternative to the answer involving converting the array of MySorter values into an array of Fixnum values is to expand the capability of your <=> method to handle Fixnum comparisons by including the following as the first statement in the block:

other = MySorter.new(other) if other.class == 'Fixnum'

There may be more elegant/efficient mechanisms to achieve this, but you get the idea.

Your problem comes in because you have not overridden == in MySorter.

You have an array of MySorter objects which you are then attempting to compare to the array of fixnums, whereas what you want to compare is the contents of the MySorter objects.

Define

  def == (other)
    other == value
  end

in MySorter and your problem is resolved. I think the default ruby == operator compares object ids or similar, which will obviously fail in your vanilla case, since a MySorter is not a Fixnum.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top