Chapter 10 - Comparable and Enumerable
Exercise 1: Comparing grades
We need a Ruby class to represent student letter grades from “A” through “F”. If you’re not familiar with the system, grades consist of the letters “A”, “B”, “C”, “D”, and “F”, with “A” being the best, and “F” being the worst.
The class will need letter
and letter=
accessor methods for the letter grade. The letter=
method should validate the letter being assigned, and raise an exception if it’s not “A”, “B”, “C”, “D”, or “F”. It should also include an initialize
method, so that we can pass a letter to Grade.new
and have it assigned to the letter
attribute.
We also need to be able to compare grades with the <
, >
, and ==
operators. An “A” grade should be considered “greater than” a “C” grade, an “F” grade should be “less than” a “D” grade, etc.
class Grade
include Comparable
VALID_LETTERS = ["A", "B", "C", "D", "F"]
attr_reader :letter
def initialize(letter)
self.letter = letter
end
def letter=(value)
unless VALID_LETTERS.include?(value)
raise "#{value} is not a valid grade letter"
end
@letter = value
end
def <=>(other)
if other.letter < letter
return -1
elsif other.letter > letter
return 1
else
return 0
end
end
end
a_grade = Grade.new("A")
b_grade = Grade.new("B")
c_grade = Grade.new("C")
d_grade = Grade.new("D")
f_grade = Grade.new("F")
puts "a_grade > c_grade: #{a_grade > c_grade}"
puts "f_grade < d_grade: #{f_grade < d_grade}"
puts "b_grade > a_grade: #{b_grade > a_grade}"
puts "a_grade == a_grade: #{a_grade == a_grade}"
The above code outputs:
a_grade > c_grade: true
f_grade < d_grade: true
b_grade > a_grade: false
a_grade == a_grade: true