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, like this:

a_grade = Grade.new("A")

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. So this code:

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}"

Should output:

a_grade > c_grade: true
f_grade < d_grade: true
b_grade > a_grade: false
a_grade == a_grade: true

Create a Grade class that mixes in the Comparable module, and implements the <=> method, so that all these operations are supported.

Hint: Ruby’s String class also mixes in Comparable, so you can compare strings based on alphabetical order with the <, >, and == operators. So "A" < "F" would return true, and "A" > "F" would return false. Of course, since the grade “F” is actually less than the grade “A”, you’ll need to reverse result of the comparison.

When you’re ready, have a look at our solution.