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

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).

有帮助吗?

解决方案

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]

其他提示

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.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top