If we have <, >, and ==, the total order is determined by those. Why do we need <=>?
-
http://stackoverflow.com/questions/827649/what-is-the-ruby-spaceship-operator – Andrey Deineko Jun 10 '15 at 23:21
-
1See the 2nd answer in the link provided by @AndreyDeineko. By implementing `<=>` and including the `Comparable` module you get all sorts of nice stuff. – pjs Jun 10 '15 at 23:58
-
@pjs, answers to SO questions don't respond to `<=>`, insofar as order of appearance is concerned. :-) – Cary Swoveland Jun 11 '15 at 00:28
-
@CarySwoveland Should have said 2nd most popular... – pjs Jun 11 '15 at 01:47
5 Answers
we Don't need <=>.
a<=>b
is equivalent to:
if a<b
return -1
elsif a>b
return 1
else
return 0
end
It is there for convenience and it was taken from perl.
- 5,567
- 4
- 37
- 66
-
I don't understand your point. We certainly need the method `<=>` as other built-in methods rely on it. And yes, the result of `<=>` could be obtained in other ways, but the same could be said about nearly all built-in methods. – Cary Swoveland Jun 11 '15 at 00:23
-
@CarySwoveland I see your point. The way I understood the question, OP was confused about what `<=>` did. To me it seemed like he was under the impression that <=> let you do something you could't do with `<`,`>`, and `=`. That was the premise under which I chose my wording. – Luke Jun 11 '15 at 00:33
-
@CarySwoveland I mean't "don't need" the same way we "don't need" `or` because we have `not` + `and` – Luke Jun 11 '15 at 00:35
-
@CarySwoveland I think LukeP means "we don't need [to explicitly define] `<=>` [given that `<`, `==`, and `>` are defined]." – sawa Jun 11 '15 at 00:46
<=> is the basis of Comparable, so you don't have to implement all of the compare functions yourself. It's easier and less error-prone to just implement one function instead of three.
- 21,472
- 14
- 74
- 123
The "spaceship" operator is for comparison, not equality. It's similar in concept to C's strcmp function.
From the String class:
string <=> other_string→ -1, 0, +1 or nilComparison — Returns -1, 0, +1 or nil depending on whether string is less than, equal to, or greater than other_string.
In short, == returns a boolean expressing equality, while <=> returns a number expressing comparative value. If the first object is of greater value than the second, <=> returns +1. If it's of lesser value, -1 is returned. If the two have the same value, 0 is returned.
The "value" of an object can be defined to be just about anything. For String, however, <=> checks the lexicographic ordering of the two arguments.
Therefore:
"abc" == "abc" # true
("abc" <=> "abc") == 0 # true
This operator is sometimes called a "signum" function. It provides the most concise way to customize sort order. For example:
require "ostruct"
# Fake "rows" with OpenStructs
my_data = [
OpenStruct.new({ :name => "Ben", :age => 50 }),
OpenStruct.new({ :name => "Abe", :age => 50 }),
OpenStruct.new({ :name => "Cab", :age => 51 })
]
# Sort by age descending, then name ascending
puts my_data.sort { |a, b| 2 * (b.age <=> a.age) + (a.name <=> b.name) }
This works because the value from <=> is always -1, 0, or 1. I don't know of a more efficient way to do general-purpose sorting.
- 322
- 2
- 9
You are correct that there is redundancy between <, ==, > and <=>. In fact, when <, ==, > are defined, <=> is automatically defined.
- 165,429
- 45
- 277
- 381