Skip to content

Instantly share code, notes, and snippets.

@jaymcgavren
Last active August 29, 2015 14:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jaymcgavren/08df8a99f7b3de6459a9 to your computer and use it in GitHub Desktop.
Save jaymcgavren/08df8a99f7b3de6459a9 to your computer and use it in GitHub Desktop.
The `PlayerScore` class represents a player's completion grade in a video game. For some inexplicable reason, the possible grades, from best to worst, are: "S+", "S", and "A". This class implements the spaceship operator, so that it can mix in `Comparable`.
class PlayerScore
include Comparable
attr_accessor :grade
def <=>(other)
return 0 if grade == other.grade
if grade == "S+"
return 1
elsif grade == "A"
return -1
else
if other.grade == "S+"
return -1
else
return 1
end
end
end
end
first_score = PlayerScore.new
first_score.grade = "S+"
second_score = PlayerScore.new
second_score.grade = "S"
puts first_score <=> second_score # => 1
puts second_score <=> first_score # => -1
@jaymcgavren
Copy link
Author

Are there other ways to implement <=> that are more concise (without being too obscure)? Are there other ways to implement <=> that are less concise, but clearer?

@jaymcgavren
Copy link
Author

A suggestion from Logan Barnett reduced this to:

class PlayerScore                          

  include Comparable                       

  attr_accessor :grade                     

  def <=>(other)                           
    ranks = {"S+" => 3, "S" => 2, "A" => 1}
    ranks[grade] <=> ranks[other.grade]    
  end                                      

end                                        

...Which seems both shorter and clearer. Unless somebody else knows a more widely-used solution, I think I'm going with this. Thanks for looking, folks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment